彻底解决Fragment重叠的问题
来源:互联网 发布:python取小数点后两位 编辑:程序博客网 时间:2024/04/29 07:10
在布局应用一级页面时很多App都会采取BottomBar + Fragment切换来构建。一般Fragment会使用FragmentManager管理,就是在一个FrameLayout构成的ContentView上做show和hide,
在这里有一个问题需要注意,在这种有多个按钮处于一个屏幕可以快速切换Fragment的UI布局下,不要使用add和replace去切换fragment,使用show和hide去切换是最好的选择,因为show和hide本质上是在控制Fragment中View的Visiblity,而执行replace则会触发fragment的detach()函数与Activity解除关联,如果此时用户快速点击,在detach还没执行完就执行attach(),很容易产生IllegalStateException:no host;应用直接崩溃。
使用show和hide很容易出现的问题就是承载Fragmen的Activity在旋转屏幕,资源不足被释放资源然后恢复重建这些情况下,被承载的Fragment在恢复时没能正确恢复状态,然后全部都显示了出来。解决这个问题的核心就是在Fragment恢复时全部隐藏,然后根据当前显示的Fragment的TAG显示Fragment。
本来想把这段代码封装成一个Activity基类,后面想想应用一级的需求页面千奇百怪,封装了也没什么通用性,就在这里记录一下,分享一下顺便备忘了=。=
上代码:
public abstract class MainActivity extends BaseActivity { private static final String SAVED_CURRENT_ID = "currentId"; public static final List<String> PAGE_TAGS = new ArrayList<>(); private List<Class<? extends BaseFragment>> fragmentClasses = Arrays.asList(HomeFragment.class, MoreFragment.class, ProfileFragment.class); //自定义的Fragment,主要目的是在初始化时能够通过循环初始化,与重建时的恢复统一 private List<Fragment> fragments = new ArrayList<>(); private FragmentManager mFragmentManager; private int currentId = 0; @Override public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) { super.onCreate(savedInstanceState, persistentState); setContentView(R.layout.activity_main); initFragments(); } private void initFragments(Bundle savedInstanceState) { mFragmentManager = getSupportFragmentManager(); for(int i = 0; i < fragments.size(); i++) { fragments.set(i, mFragmentManager.findFragmentByTag(PAGE_TAGS.get(i))); if(fragments.get(i) == null) { try { fragments.set(i,fragmentClasses.get(i).newInstance()); } catch (Exception e) { e.printStackTrace(); } } //先重置所有fragment的状态为隐藏,彻底解决重叠问题 if(fragments.get(i).isAdded()) { mFragmentManager.beginTransaction() .hide(fragments.get(i)) .commitAllowingStateLoss(); } } if(savedInstanceState != null) { int cachedId = savedInstanceState.getInt(SAVED_CURRENT_ID, 0); if(cachedId >= 0 && cachedId <= 4) { currentId = cachedId; } } switchFragment(currentId, false); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt(SAVED_CURRENT_ID, currentId); } private void switchFragment(int index) { switchFragment(index, true); } private void switchFragment(int index, boolean anim) { /* Fragment 切换 */ FragmentTransaction transaction = mFragmentManager.beginTransaction(); if(anim) { //显示切换动画 if(index > currentId) { transaction.setCustomAnimations(R.anim.slide_right_in, R.anim.slide_left_out); } else { transaction.setCustomAnimations(R.anim.slide_left_in, R.anim.slide_right_out); } } if(fragments.get(index).isAdded()) { transaction.hide(fragments.get(currentId)); transaction.show(fragments.get(index)); } else { transaction.hide(fragments.get(currentId)); transaction.add(getFragmentContainerLayoutRes(), fragments.get(index), PAGE_TAGS.get(index)); transaction.show(fragments.get(index)); } transaction.setTransitionStyle(FragmentTransaction.TRANSIT_FRAGMENT_FADE); transaction.commitAllowingStateLoss(); currentId = index; } }
0 0
- 彻底解决Fragment重叠的问题
- Fragment重叠的问题
- Android fragment 重叠问题的解决方法
- Android fragment 重叠问题的解决方法
- Android fragment 重叠问题的解决方法
- fragment界面重叠问题的终极解决方法
- Fragment重叠问题引发的思考
- Android fragment 重叠问题的解决方法
- Fragment系列之视图重叠的问题
- 完美解决Fragment重叠的问题
- Fragment 重叠问题的原因及解决办法
- Fragment重叠问题引发的思考
- fragment重叠问题
- Fragment重叠问题
- Android fragment 重叠问题
- 解决Fragment重叠问题
- fragment重叠问题
- Fragment 重叠(重影)问题
- 下载和安装 Visual Studio 2015 软件 的详细步骤图文教程
- 我面试到底问什么?
- 文件转写
- how to quit webview player
- 从0开始学习 GitHub 系列之「向GitHub 提交代码」
- 彻底解决Fragment重叠的问题
- OpenCV 3 - 编译更强大的OpenCV(二) - 拼人品时刻
- Python3 pip 解决问题: error: Unable to find vcvarsall.bat
- 第十三章 编程练习
- My-学编程之路
- C# winform 无边框窗体鼠标点击移动事件
- Python3 大型网络爬虫实战 001 --- 搭建开发环境
- Python --- Scrapy 命令
- 解决问题: pywin32 安装后出现 import win32api ImportError DLL load failed