美文网首页Android TipsAndroid开发Android开发
Android重新打开APP应用程序或activity后frag

Android重新打开APP应用程序或activity后frag

作者: 喂_balabala | 来源:发表于2018-01-02 10:29 被阅读44次

    问题发生的场景:

    屏幕旋转
    activity被强杀后重启
    应用在后台被挤出后重新打开
    。。。
    

    产生原因:

    FragmentState没有保存隐藏还是显示这个状态,当生命周期又走一次的时候又创建了一次fragment,所以导致重叠
    
    解决方法1:

    (太low,不推荐使用。不能恢复重启前的界面)

    直接在包含Fragment的Activity中复写onSaveInstanceState()方法,使其空实现;(在BaseActivity实现)不传递任何信息,自然不会恢复fragment,也就没有重叠了,全部重新创建一次

    @Override  
     protected void onSaveInstanceState(Bundle outState) {  
       //super.onSaveInstanceState(outState);  
     }
    

    解决方法2:

    (墙裂推荐)
    onSaveInstanceState保存状态,根据需要恢复。有findTag肯定就有setTag的地方。

     @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            initFragments();
            if (savedInstanceState!=null){
                mRadioGroup.setOnCheckedChangeListener(this);
                mIndex = savedInstanceState.getInt(CURRENT_INDEX, 0);
                hideFragment();
            }else {
                initRadioGroupChecked();
            }
        }
    
        private void hideFragment() {
            FragmentManager supportFragmentManager = getSupportFragmentManager();
            mHomeFragment= (HomeFragment) supportFragmentManager.findFragmentByTag(HomeFragment.class.getName());
            mInvestFragment= (InvestFragment) supportFragmentManager.findFragmentByTag(InvestFragment.class.getName());
            mFindFragment= (FindFragment) supportFragmentManager.findFragmentByTag(FindFragment.class.getName());
            mMyFragment= (MyFragment) supportFragmentManager.findFragmentByTag(MyFragment.class.getName());
            FragmentTransaction transaction = supportFragmentManager.beginTransaction();
            if (mHomeFragment!=null) transaction.hide(mHomeFragment);
            if (mInvestFragment!=null) transaction.hide(mInvestFragment);
            if (mFindFragment!=null) transaction.hide(mFindFragment);
            if (mMyFragment!=null) transaction.hide(mMyFragment);
            transaction.commit();
        }
    
        private void initRadioGroupChecked() {
            mRadioGroup.setOnCheckedChangeListener(this);
            mRadioGroup.check(R.id.rb_home);
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction ft = fragmentManager.beginTransaction();
            ft.add(R.id.fragment_container, mSparseArray.get(0),mSparseArray.get(0).getClass().getName()).show(mSparseArray.get(0));
            ft.commit();
        }
    
        @Override
        public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
            outState.putInt(CURRENT_INDEX,mIndex);
            super.onSaveInstanceState(outState);
        }
    

    不知你们发现没有,在hideFragment方法里面明明把所有的fragment都隐藏了,但是重新打开应用还是呈现出退出之前的界面,因为我使用了有两个形参的onSaveInstanceState方法。PersistableBundle 就是用来做数据持久化的,所有还是显示上一场退出的那个界面。此时呈现的界面其实是新建的,而不是之前的,之前的已经被隐藏了。当然也可以使用只有一个形参的onSaveInstanceState方法。但是就要自己手动再show一个新的fragment出来。可能有人觉得在hideFragment不隐藏就好了,但是切换的时候还是要用findFragmentByTag找出来再隐藏,不然还是有重叠的问题。

    解决方法3:

    (方法3思路是最高端的,但还是推荐方法2)

    在basefragment中重写onSaveInstanceState,既然系统没保存那就手动保存

        private String FRAGMENT_STATE="fragment_state";
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if (savedInstanceState!=null){
                boolean isHidden = savedInstanceState.getBoolean(FRAGMENT_STATE, false);
                FragmentTransaction transaction = getFragmentManager().beginTransaction();
                if (isHidden){
                    transaction.hide(this);
                }else {
                    transaction.show(this);
                }
                transaction.commit();
            }
    
        }
    
        @Override
        public void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            outState.putBoolean(FRAGMENT_STATE,isHidden());
        }
    

    然后会发现在主activity切换fragment的时候还是会有重叠问题。因为你在切换的时候可能做了隐藏的操作,但是其实你隐藏的是新new出来的fragment,而不是重启之前的fragment。所以还是要在主activity的oncreate中做判断然后写方法2中的hideFragment方法。所以我还是推荐方法2.

    总结

    如果你是想解决在APP主界面底部按钮切换fragment导致的重叠问题选择方法2。如果你只是单纯的多个fragment造成的重叠问题可以选择方法3。

    https://blog.csdn.net/weixin_37165769/article/details/79892329

    相关文章

      网友评论

        本文标题:Android重新打开APP应用程序或activity后frag

        本文链接:https://www.haomeiwen.com/subject/vlrfnxtx.html