彻底解决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
原创粉丝点击