片段之间的事务仅在一个ActionBar选项卡内

and*_*ias 7 tabs android android-fragments android-activity android-actionbar

我有一个带有三个选项卡(ActionBar选项卡)的应用程序,每个选项卡一次只有一个片段.

TabListener

TabsActivity

Tab1 - > ListFragment1 - > ListFragment2 - > Fragment3

Tab2 - > Tab2Fragment

Tab3 - > Tab3Fragment

问题是当我从ListFragment1到ListFragment2创建FragmentTransaction(在OnListItemClicked内)时,其他选项卡中的片段也会更改为ListFragment2.

最后,我想仅在选项卡内更改片段并保留其他选项卡的状态.

我已经保存了状态(OnSavedInstance()).你知道我在这里缺少什么吗?

一些代码:

public class TabsActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tabs);

        // setup Action Bar for tabs
        ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // instantiate fragment for the tab
        Fragment networksFragment = new NetworksFragment();
        // add a new tab and set its title text and tab listener
        actionBar.addTab(actionBar.newTab().setText("Tab1")
                .setTabListener(new TabsListener(ListFragment1)));

        // instantiate fragment for the tab
        Fragment historyFragment = new HistoryFragment();
        // add a new tab and set its title text and tab listener
        actionBar.addTab(actionBar.newTab().setText("Tab2")
                .setTabListener(new TabsListener(Tab2Fragment)));

        // instantiate fragment for the tab
        Fragment settingsFragment = new SettingsFragment();
        // add a new tab and set its title text and tab listener
        actionBar.addTab(actionBar.newTab().setText("Tab3")
                .setTabListener(new TabsListener(Tab3Fragment)));
    }
}
Run Code Online (Sandbox Code Playgroud)
public class TabsListener implements ActionBar.TabListener {

    private Fragment frag;


    // Called to create an instance of the listener when adding a new tab
    public TabsListener(Fragment networksFragment) {
        frag = networksFragment;
    }

    @Override
    public void onTabReselected(Tab arg0, FragmentTransaction arg1) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {    
        ft.add(R.id.fragment_container, frag, null);
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        ft.remove(frag);        
    }
}
Run Code Online (Sandbox Code Playgroud)
public class ListFragment1 extends ListFragment {

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {

        getListView().setItemChecked(position, true);

        ListFragment2 fragment2 = ListFragment2.newInstance(position);

        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.replace(R.id.fragment_container, fragment2);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        ft.addToBackStack(null);
        ft.commit();
    }
}
Run Code Online (Sandbox Code Playgroud)

jsa*_*ler 6

你没有遗漏任何东西(或者我也错过了).

我搜索得很长,很难找到"正确"的方法,但我找不到任何东西.我最终做的是编写自己的backstack逻辑.不幸的是,我的雇主拥有我的代码所以我不能逐字分享,但这是我的方法:

enum为每个标签创建一个条目.我们称之为TabType.现在创建一个tabStacks类型的实例变量HashMap<TabType, Stack<String>>.现在,您可以为每个选项卡实例化一个堆栈 - 每个堆栈都是一个标记列表,如下所示Fragment.getTag().这样,您不必担心存储引用,Fragments以及在旋转设备时它们是否会消失在您身上.每当你需要引用a时Fragment,从堆栈中取出正确的标签并使用FragmentManager.findFragmentByTag().

现在,无论何时你想要Fragment一个标签,生成一个新标签(我用过UUID.randomUUID().toString())并在你的电话中使用它FragmentTransaction.add().然后将标签推到堆栈顶部,以显示当前显示的选项卡.

要小心:当你想在一个旧片段之上推一个新片段时,不要使用旧片段remove(),因为它FragmentManager会认为它已经消失并且它将被清除.确保detach()它,然后attach()它.仅remove()在您永久弹出a时Fragment使用,并且仅add()在您第一次显示时使用.

然后,你将不得不添加一些相对简单的逻辑TabListener.取消选择选项卡时,只需peek()在其堆栈和detatch()相关的片段中.当选择了一个标签,peek()在顶部的是堆和attach()该片段.

最后,您将不得不处理Activity生命周期怪癖(如方向更改).保留您MapStacks当前选择的标签,然后在您的标签中再次打开包装onCreate().(你没有得到这个包装和免费拆包,但它很容易做到.)幸运的是你的TabType枚举是Serializable这样的,所以放入一个应该是微不足道的Bundle.