我有一个包含三个选项卡(ActionBar 选项卡)的应用,每个选项卡一次包含一个 fragment 。
标签监听器
标签 Activity
Tab1 -> ListFragment1 -> ListFragment2 -> Fragment3
Tab2 -> Tab2Fragment
Tab3 -> Tab3Fragment
问题是当我创建从 ListFragment1 到 ListFragment2 的 FragmentTransaction(在 OnListItemClicked 内)时,其他选项卡内的 fragment 也更改为 ListFragment2。
最后,我只想更改选项卡内部的 fragment 并保留其他选项卡的状态。
我已经在保存状态 (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();
}
}
最佳答案
您没有遗漏任何东西(或者我也遗漏了它)。
我长期努力地寻找一种“正确”执行此操作的方法,但我找不到任何东西。我最终做的是编写自己的后台逻辑。 不幸的是,我的雇主拥有我的代码,因此我无法逐字分享任何内容,但这是我的方法:
创建一个 enum
每个选项卡都有一个条目。我们称它为TabType
.
现在创建一个实例变量 tabStacks
类型 HashMap<TabType, Stack<String>>
.现在您可以为每个选项卡实例化一个堆栈 - 每个堆栈都是一个标签列表,由 Fragment.getTag()
指定。 .这样您就不必担心存储对 Fragments
的引用以及当您旋转设备时它们是否会在您身上消失。任何时候您需要引用 Fragment
, 从堆栈中取出正确的标签并使用 FragmentManager.findFragmentByTag()
.
现在无论何时你想推送 Fragment
在选项卡上,生成一个新标签(我使用了 UUID.randomUUID().toString()
)并在调用 FragmentTransaction.add()
时使用它.然后将标签推到当前显示的选项卡的堆栈顶部。
注意:当您想将新 fragment 推到旧 fragment 之上时,不要remove()
旧的,自FragmentManager
会认为它消失了,它会被清理干净。务必detach()
它,然后 attach()
稍后。仅使用 remove()
当你永久弹出一个 Fragment
, 并且只使用 add()
第一次显示它。
然后,您必须向 TabListener
添加一些相对简单的逻辑.取消选择选项卡时,只需 peek()
在它的堆栈和detatch()
关联的 fragment 。选择选项卡后,peek()
在那个堆栈的顶部和attach()
那个 fragment 。
最后,您必须处理 Activity 生命周期的怪癖(例如方向更改)。坚持你的Map
的 Stacks
以及当前选择的选项卡,并在你的 onCreate()
中再次解压它. (您不会免费获得此打包和拆包,但这很容易做到。)幸运的是您的 TabType
枚举是 Serializable
所以放入 Bundle
应该是微不足道的.
关于android - 仅在一个 ActionBar Tab 内的 fragment 之间的事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7879635/