Android ViewPager加载多个Fragment切换问题

先看问题,如图所示(不会做类似小视频那种图啊,有会做的小伙伴求帮忙啊):

Android ViewPager加载多个Fragment切换问题_第1张图片

首先来分析问题:造成这种情况的是,viewpager默认加载当前fragment左右相邻的两个fragment,就是所谓的预加载,如图中所示,当page0->page1->page2的时候,page0已经释放掉,那么释放到底是怎么回事呢?
1.先做一个测试准备,在fragment生命周期方法中打印提示文字(本次测试只看page0的打印):


Android ViewPager加载多个Fragment切换问题_第2张图片
还有onCreateView中也打印了

2.切换到page0->page1->page2的时候,看看打印如何:


由图中可以看到,当切换到page2的时候,page0已经走到了onDestroy
3.page0->page1->page2->page1的时候,看看如何打印:

Android ViewPager加载多个Fragment切换问题_第3张图片

由途中可以看到,当再次切换回page1的时候,page0重新走了onCreate方法

解决办法1:

既然page0页面已经销毁,那么我们不让他销毁就可以了,下面涉及到viewpager的一个方法setOffscreenPageLimit(),viewpager.setOffscreenPageLimit(fragmentList.size) 亲测可以解决,但是这个方法存在一个问题,如果页面过多,内存是受不了的啊

解决办法2:

既然每次都走onCreateView,那控件应该都加载了一遍,那么为什么什么都不显示呢?
打log来测试下view是否为空:


Android ViewPager加载多个Fragment切换问题_第4张图片
打印页面销毁之后view是否为空
由上图可见,虽然每次都是走oncreate,但和首次加载oncreate的时候相比,区别就是view并不为空,那我先假设问题就出在这里,既然不为空,那么把view移除再加载就好啦

在网上找到的方法是这样的,相关问题都是这样

if (view != null) {
var parent:ViewGroup? = view!!.parent as? ViewGroup
LogUtil.d("是否为空", "view ->"+(view == null).toString())
LogUtil.d("是否为空", "parent ->"+(parent == null).toString())
if(parent != null){
parent!!.removeView(view!!)
}
return view
}

经过测试,好使,但是测试过程中发现一个问题:

parent一直为null,暂时借用论坛中一位大神的说法,有时间深究下再更新

第一种方法是你通过反射器获取生成了一个View,相当于new,它没有依赖于哪个父控件,因此是null。第二种方法是先有系统setContentView之后
你获取到的,相当于View被attach之后,你再读取,(在哪里有看到,系统createView时会自动创建一个FragmentLayout),因此它是有父控件的。

那么问题来了,直接return view 不行么?上代码测试:

if (view != null) {
return view
}

结果一样,目前还没发现其他几句代码有什么用处。(如果哪位大神知道其中的猫腻,跪求告知,感激不尽!)

这里可以暂时下个结论:网上疯传的各种办法并不见得就是最好的,要经过自己的判断再去使用

解决办法3:

参考办法2,经过2中的测试发现,虽然生命周期走了onDestroy方法,但是布局并没有销毁,对象依然存在,再次onCreate的时候,只是恢复或者加载数据的操作,那么我们是否可以判断view是否为null,如果为null说明第一次加载,如果不是null,就代表已经有了,不用加载布局了呢?
直接上代码:

if(view == null){
view = inflater!!.inflate(R.layout.fragment_my_release, container, false) as ViewGroup
}

经测试,效果是一样的,不同的是这种办法其他代码都要走,如果这时候需要更新数据操作,可以选择适当用。

本文内容内容不断更新,如果有大佬有好的意见,欢迎指教!

二维码.jpg

推荐下本人的微信公众号,本博客及其他方面的消息会定期同步到公众号上面!

你可能感兴趣的:(Android ViewPager加载多个Fragment切换问题)