Fragment重叠问题引发的思考

参考:

http://stackoverflow.com/questions/16189088/overlapping-hidden-fragments-after-application-gets-killed-and-restored

http://stackoverflow.com/questions/18274732/android-fragments-overlapping-issue?answertab=active#tab-top

Fragment重叠问题相信很多开发者都遇到个这个问题,也解决个这个问题,前段时间偶然发现,公司项目偶然出现了Fragment重叠的Bug,心里不由一紧,赶紧去stackoverflow搜索了一番,找到了好几种解决方案,最终问题是解决了,不过心里留下了很多疑问(为什么会出现重叠?为什么这么处理之后可以解决问题?这样写会不会引发其他问题?),带着我决定写个Demo去分析下每种解决方法的原理以及可能带来的负面影响。

一、问题重现

Demo是常见的用Fragment实现的Tab切换,拿了网上现成的Demo改了一下,先给个Fragment重叠的效果图:

这里写图片描述

在Fragment切换时,采用的show/hide的方式,原理是显示某个Fragment时,先把其他几个Fragment先隐藏掉:

private void setTabSelection(int index) {
        clearSelection();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        hideFragments(transaction);
        switch (index) {
            case 0:
                messageImage.setImageResource(R.drawable.message_selected);
                messageText.setTextColor(Color.WHITE);
                if (messageFragment == null) {
                    messageFragment = new NormalListFragment();
                    transaction.add(R.id.content, messageFragment);
                } else {
                    transaction.show(messageFragment);
                }
                break;
            case 1:
                contactsImage.setImageResource(R.drawable.contacts_selected);
                contactsText.setTextColor(Color.WHITE);
                if (contactsFragment == null) {
                    contactsFragment = new ContactsFragment();
                    transaction.add(R.id.content, contactsFragment);
                } else {
                    transaction.show(contactsFragment);
                }
                break;
            case 2:
                newsImage.setImageResource(R.drawable.news_selected);
                newsText.setTextColor(Color.WHITE);
                if (newsFragment == null) {
                    newsFragment = new NewsFragment();
                    transaction.add(R.id.content, newsFragment);
                } else {
                    transaction.show(newsFragment);
                }
                break;
            case 3:
            default:
                settingImage.setImageResource(R.drawable.setting_selected);
                settingText.setTextColor(Color.WHITE);
                if (settingFragment == null) {
                    settingFragment = new SettingFragment();
                    transaction.add(R.id.content, settingFragment);
                } else {
                    transaction.show(settingFragment);
                }
                break;
        }
        transaction.commit();
    }

由于Fragment重叠问题是发生在某种特定的情况下,所以在常规环境下很难复现,所以需要在Android 手机开发者选项中把不保留活动这个选项打开,这样每次进入新的Activity,旧的Activity就会马上销毁。

这里写图片描述

问题分析

假设现在处在第一个Tab 图片列表(NormalListFragment),然后点击某个Item进入详情页,由于不保留活动,Fragment所在的Activity会销毁掉。然后,我们从详情页返回到图片列表,Activity会重建,Fragment会重新绑定, 整个过程Activity和Fragment的生命周期方法调用Log如下:

06-18 21:35:36.479 3004-3004/com.jx.androiddemos I/FragmentLearn: NormalListFragment  onPause
06-18 21:35:36.479 3004-3004/com.jx.androiddemos I/FragmentLearn: FragmentMainActivity  onPause
06-18 21:35:36.893 3004-3004/com.jx.androiddemos I/FragmentLearn: FragmentMainActivity  onSaveInstanceState   Bundle[{android:viewHierarchyState=Bundle[{android:views={
  16908290=android.view.AbsSavedState$1@6962f3e, 2131624006=android.view.AbsSavedState$1@6962f3e, 2131624007=android.view.AbsSavedState$1@6962f3e, 2131624008=android.support.v7.widget.Toolbar$SavedState@bda98cc, 2131624009=android.view.AbsSavedState$1@6962f3e, 2131624052=android.view.AbsSavedState$1@6962f3e, 2131624053=android.view.AbsSavedState$1@6962f3e, 2131624054
  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值