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

我有一个应用程序与三个选项卡(ActionBar选项卡),每一个一个片段一次。

TabListener

TabsActivity

Tab1 – > ListFragment1 – > ListFragment2 – > Fragment3

Tab2 – > Tab2Fragment

Tab3 – > Tab3Fragment

问题是当我从ListFragment1创buildFragmentTransaction(在OnListItemClicked内)到ListFragment2,其他选项卡内的片段也更改为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))); } } 

 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); } } 

 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(); } } 

Solutions Collecting From Web of "仅在一个ActionBar选项卡内的片段之间的事务"

你不会错过任何东西(或者我也错过了)。

我search了很长时间,很难find“正确”的方法,但我找不到任何东西。 我最终做的是写我自己的后台逻辑。 不幸的是,我的雇主拥有我的代码,所以我不能分享任何逐字,但这是我的方法:

为每个选项卡创build一个enum 。 我们称之为TabType 。 现在创build一个types为HashMap<TabType, Stack<String>>的实例variablestabStacks 。 现在,您可以为每个选项卡实例化一个堆栈 – 每个堆栈都是由Fragment.getTag()指定的标记列表。 这样,您不必担心存储对Fragments引用,以及在旋转设备时是否会消失。 任何时候你需要一个Fragment的引用,从堆栈中取出正确的标签并使用FragmentManager.findFragmentByTag()

现在,无论何时您想将Fragment推送到选项卡上,都会生成一个新的标签(我使用了UUID.randomUUID().toString() ),并在调用FragmentTransaction.add()使用它。 然后将标签推到当前显示的选项卡的堆栈顶部。

注意:当你想把一个新的片段放到一个旧的片断上时,不要remove()旧的FragmentManager remove() ,因为FragmentManager会认为它已经消失了,并且会被清理掉。 一定要detach() ,然后再attach() 。 永久popupFragment时只使用remove() ,并且只在第一次使用add()时才显示它。

然后,你必须添加一些相对简单的逻辑到你的TabListener 。 当一个选项卡被取消选中时,只需在其堆栈中peek()detatch()关联的Fragment。 当select一个标签时, peek()在堆栈的顶部attach()该片段。

最后,你将不得不处理Activity生命周期怪癖(如方向更改)。 坚持您的Stacks Map以及当前选定的选项卡,并在onCreate()再次解压缩。 (你没有得到这个包装,也没有免费的开箱,但是很容易做到。)幸运的是,你的TabType枚举是可Serializable所以把它放入Bundle应该是微不足道的。