我正在开发的应用程序中的一个屏幕有多个子屏幕实现为由底部导航栏控制的片段。
这是我在用户希望切换片段时的代码:
protected final void switchTab(int index) {
if (curTabIndex == index) {
return;
}
if (bottomNavigationBar.getCurrentTabPosition() != index) {
bottomNavigationBar.selectTabAtPosition(index, true);
}
curTabIndex = index;
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.setCustomAnimations(R.anim.alpha_in, R.anim.alpha_out);
detachCurrentFragment(ft);
// Attempt to reattach previous fragment.
BottomTabbedActivityFragment fragment = reattachExistingFragment(ft);
if (fragment != null) {
ft.commit();
} else {
fragment = fragments.get(curTabIndex);
ft.add(contentContainer.getId(), fragment, (fragment.getClass().getName()));
ft.commit();
}
fragmentManager.executePendingTransactions();
curFragment = fragment;
}
/**
* Attemps to detach any current fragment if it exists, and if none is found, returns;
*
* @param ft the current transaction being performed
*/
private void detachCurrentFragment(FragmentTransaction ft) {
// Attempt to detach current fragment.
if (curFragment != null) {
ft.hide(curFragment);
}
}
/**
* Will attempt to reattach a previous fragment in the FragmentManager, or return null if not able to,
*
* @param ft current fragment transaction
* @return Fragment if we were able to find and reattach it
*/
@Nullable
private BottomTabbedActivityFragment reattachExistingFragment(FragmentTransaction ft) {
Fragment fragment = fragmentManager.findFragmentByTag(fragments.get(curTabIndex).getTag());
if (fragment != null) {
ft.show(fragment);
}
return (BottomTabbedActivityFragment) fragment;
}
使用上面的片段,我能够顺利地在片段之间切换。但是,这种方法有一个大问题:添加的las片段尽管被隐藏,但仍保留了用户输入。
换句话说,假设我的用户经历了这个更改序列:
子屏幕A
-
从逻辑上讲,输入现在将由子屏幕A
处理,因为子屏幕C
现在是隐藏的。但现实情况并非如此:子屏幕C
仍然是接收用户输入的人。
在尝试滚动Subsreen A
时,我甚至可以看到一些显示子屏幕C
的故障。
有什么我能解决的吗?
P. S.,我现在拥有的那些子屏幕重新初始化的成本非常高。它们都有复杂的视图层次结构,用户需要在它们之间切换很多。我尝试了attach()
/detach()
,但在我的测试中变得如此缓慢。
只需将android: clickable="true"
放在片段布局文件的根视图中。