前言:最近项目中用BottomNavigationView动态添加几个Fragment于FrameLayout中,bug就在我切换其他APP操作一会后,再回到当前APP,有很大概率出现fragment重叠的现象。



一、Fragment 重叠原因分析

切换到其他APP时,Android由于内存资源紧张,fragmen所在activity已经被销毁,但是保存了activity的状态:

Android有一个种特殊情况,就是app运行在后台的时候,内存资源紧张的时候导致把app的资源全部回收(销毁Activity),这时把app再从后台返回到前台时,app会重启Activity。

这属于非正常销毁,尽管Activity实例被销毁,但系统会调用Activity的onSaveInstanceState()保存其状态,这样,如果用户导航回该Activity,系统会使用onCreate中的参数savedInstanceStatea保存的状态数据恢复之前的fragment,并重新创建activity新实例,这样相当于又再次add了fragment进去,所以出现了重叠现象。


二、解决方案:(亲测有效)

findFragmentbyTag:

即在add()或replace()时绑定一个tag,一般用fragment的类名作为tag,然后在发生“内存重启”时,通过findFragmentByTag()找到对应的Fragment显示show(),并hide()需要隐藏的fragment。

/*2、解决内存重启后碎片的重叠问题 */    private void initFragmen(Bundle savedInstanceState)    {        if(savedInstanceState != null)        {            // “内存重启”时调用            homepageFragment = (HomepageFragment)getSupportFragmentManager().findFragmentByTag("homepageFragment");            hotFragment = (HotFragment)getSupportFragmentManager().findFragmentByTag("hotFragment");            meFragment  = (MeFragment)getSupportFragmentManager().findFragmentByTag("meFragment");            //取出onSaveInstanceState(Bundle outState)里保存离开时的那个界面的tag,恢复到用户离开时的那个Fragment的界面            String tag = savedInstanceState.getString("lastVisibleFragment");            switch (tag)            {                case "homepageFragment":                    // 解决重叠问题                    getSupportFragmentManager().beginTransaction()                            .show(homepageFragment)                            .hide(hotFragment)                            .hide(meFragment)                            .commit();                    break;                case "hotFragment":                    // 解决重叠问题                    getSupportFragmentManager().beginTransaction()                            .show(hotFragment)                            .hide(homepageFragment)                            .hide(meFragment)                            .commit();                    topView.setVisibility(View.GONE);                    toolbar.setVisibility(View.GONE);                    break;                case "meFragment":                    // 解决重叠问题                    getSupportFragmentManager().beginTransaction()                            .show(meFragment)                            .hide(hotFragment)                            .hide(homepageFragment)                            .commit();                    topView.setVisibility(View.GONE);                    toolbar.setVisibility(View.GONE);                    break;            }        }        else        {            // 正常创建时            homepageFragment = new HomepageFragment();            hotFragment = new HotFragment();            meFragment = new MeFragment();            getSupportFragmentManager().beginTransaction()                    .add(R.id.content_fragment_layout,homepageFragment, "homepageFragment")                    .add(R.id.content_fragment_layout,hotFragment,"hotFragment")                    .add(R.id.content_fragment_layout,meFragment,"meFragment")                    .show(homepageFragment)                    .hide(hotFragment)                    .hide(meFragment)                    .commit();        }    }


三、恢复到用户离开时的那个Fragment的界面

如果你想恢复到用户离开时的那个Fragment的界面,你还需要在onSaveInstanceState(Bundle outState)里保存离开时的那个界面的tag或者下标,在“内存重启”代码块中,取出tag/下标,进行恢复。

/*5、内存销毁活动后,保存ctivity中当前显示的fragment的tag*/   @Override    protected void onSaveInstanceState(Bundle outState) {        super.onSaveInstanceState(outState);        lastVisibleFragment = getVisibleFragment();        outState.putString("lastVisibleFragment",lastVisibleFragment.getTag());   }


四、得到Activity当前显示的fragment

    /*6、得到当前Activity显示的fragment*/    private Fragment getVisibleFragment()    {        Fragment lastFragment = null;        fragmentManager = getSupportFragmentManager();        fragmentList = fragmentManager.getFragments();        for(Fragment fragment : fragmentList)        {            if (fragment != null && fragment.isVisible())            {                lastFragment = fragment;                break;            }        }        return lastFragment;    }



更多相关文章

  1. 关于Android堆内存的设置
  2. Android之——性能与内存优化
  3. android从手机内存获得图片并全屏显示
  4. android 沉浸式状态栏不会和虚拟重叠
  5. Android(安卓)启动线程OOM
  6. android 內存等使用情況(转)
  7. Android缓存的引用
  8. Android模仿jquery异步请求
  9. Android(安卓)InputMethodManager泄漏Activity

随机推荐

  1. 从另一个页面返回后,$(document).ready()无效
  2. 《锋利的jQuery》读书笔记 第5章 jQuery
  3. 在完成之前,jQuery将继续使用ajax调用。
  4. 可以直接拿来用的15个jQuery代码片段
  5. 嵌套在.get请求中的jQuery将不会执行
  6. 使用jquery 1.11.3.min.js时,jquery on cl
  7. jquery与JavaScript部分使用区别
  8. 如何更改Gmaps.js在Google地图中使用的图
  9. jQuery UI框架的Dreamweaver接口
  10. jQuery UI AutoComplete的使用