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))); } }
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(); } }
解决方法
我搜索得很长,很难找到“正确”的方法,但我找不到任何东西.我最终做的是编写自己的backstack逻辑.
不幸的是,我的雇主拥有我的代码所以我不能逐字分享,但这是我的方法:
为每个选项卡创建一个包含一个条目的枚举.我们称之为TabType.
现在创建一个类型为HashMap< TabType,Stack< String>>的实例变量tabStacks.现在,您可以为每个选项卡实例化一个堆栈 – 每个堆栈都是一个标记列表,由Fragment.getTag()指定.这样您就不必担心存储对Fragments的引用,以及在旋转设备时它们是否会消失在您身上.只要您需要对Fragment的引用,请从堆栈中获取正确的标记并使用FragmentManager.findFragmentByTag().
现在,只要您想将片段推送到选项卡上,就生成一个新标签(我使用了UUID.randomUUID().toString())并在调用FragmentTransaction.add()时使用它.然后将标签推到堆栈顶部,以显示当前显示的选项卡.
注意:当你想在一个旧片段之上推一个新片段时,不要删除()旧片段,因为FragmentManager会认为它已经消失并且它将被清除.确保分离()它,然后稍后附加().只有在永久弹出片段时才使用remove(),并且只在第一次显示片段时才使用add().
然后,您必须向TabListener添加一些相对简单的逻辑.当取消选择选项卡时,只需在其堆栈中查看()并分离()相关的片段.选择选项卡时,peek()位于该堆栈的顶部并附加()该片段.
最后,您将不得不处理Activity生命周期怪癖(如方向更改).保留您的Stacks Map以及当前选定的选项卡,然后在onCreate()中再次将其解压缩. (你没有免费获得这个打包和解压缩,但这很容易做到.)幸运的是你的TabType枚举是Serializable,因此放入Bundle应该是微不足道的.