参考:
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