美文网首页
Fragmentation如何兼容新版本的setMaxLifec

Fragmentation如何兼容新版本的setMaxLifec

作者: 恒泪 | 来源:发表于2020-05-07 19:39 被阅读0次

看这篇文章前,大家应该先对setMaxLifecycle有所了解。

本文基于 https://github.com/JantHsueh/Fragmentation 维护的1.0.5进行修改,1.0.6后续会补上

上年年末,谷歌为新版本的Fragment添加了控制其在ViewPager中的生命周期的新方式——setMaxLifecycle(而ViewPager2中默认且只有这个方式)。

ViewPager1中FragmentPagerAdapter的代码
听说后面还要把onActivityCreated砍了,注意下。

setMaxLifecycle的添加,简化了ViewPager在切换对Fragment可见性判断的复杂度,但是也增加了一些操X的问题:如果你使用了ViewPagersetMaxLifecycle。因为生命周期改变了,你的程序可能要做出相应的适配。
如果刚好你在用Fragmentation,又碰上了ViewPagersetMaxLifecycle,那么你就会发现只要打开了ViewPager所属的页面,ViewPager容器内的所有Fragment都会立刻调用了supportVisible()可见可见函数,无论这些Fragment是不是都显示了。当然,onLazyInitView懒加载也被调用了。

目前我所知道有三种解决办法,分享下

1、找作者或者接手Fragmentation项目的大佬解决这个问题。
2、自己动手丰衣足食
3、用回ViewPagerBEHAVIOR_SET_USER_VISIBLE_HINT

方法这么多,足足有三个,我们来用下排除法找答案。
第一个呢,我也提了issue了,就看接手大佬能不能看到了。
第二个呢,需要自己download整个项目下来改,下文会讲
第三个呢,如果你用的ViewPager1,这可能就是换个Adapter或者改个参数的事,如果你用的是ViewPager2,那你的工作量可能就有一点了,你自己掂量下,反正我是觉得ViewPager2不错。

怎么改嘛

注意:这个修改,我会直接弃用onActivityCreated,而使用onStart和onResume来判断Fragment是否处于活跃或显示状态,即在onResume后再调用supportVisible,请注意检查你的项目中业务逻辑顺序是否有需要调整

1、从Fragmentation下载这个库,并导入到你的项目中

我相信有点经验的开发人员都知道怎么import module。

2、从我fork的https://github.com/Ubitar/Fragmentation的fragmentation_core库中找到下方这3个文件:VisibleDelegateSupportFragmentDelegate,以及BaseSupportFragment文件,并覆盖你项目中对应的文件。

当时的Fragmentation 的版本是 androidx 1.0.5

3、然后,没了,你们引用这个本地库测试下吧,不要忘记把旧的fragmentation_core依赖去除

源码修改解析

分析内容

1、打开BaseSupportFragment,可以看到里面几乎所有的方法都是通过SupportFragmentDelegate代理的,有了解过Fragment或者Activity源码的人都知道这很Android。从SupportFragmentDelegate源码中搜索onSupportVisible函数,发现是空的。

回到BaseSupportFragment再次搜索onSupportVisible的引用,找到了调用其的VisibleDelegate
2、在VisibleDelegate中顺着Fragment的生命周期去找有关分发可见性或直接控制可见性的函数。首先onCreateonResume方法是可以排除的,在剩下的其他函数onActivityCreated()中可以找到有一个关于控制可见性的函数,initVisible()
3、调查下initVisible() 发现isFragmentVisible()很可疑,跟踪。

就那么一句话,是真正判断可见性的函数了。

那么我们写个ViewPager运行下,调试看到fragment.getUserVisibleHint()在使用setMaxLifecycle的情况下无论如何都是true,所以当ViewPager活跃时,上面所有Fragment都被认定为可见了,后面的onLazyInitView()也自然被调用了。

4、但是,先别急着修改isFragmentVisible(),由于使用了setMaxLifecycle的缘故,需要把onActivityCreated()中的内容迁移到onStart()中,遗弃onActivityCreated()

当然,BaseSupportFragmentSupportFragmentDelegate也要做出响应的修改,具体修改内容MySupportFragmentSupportFragmentDelegate注意,多了个 onViewStateRestored()
5、现在回头改isFragmentVisible(),既然setMaxLifecycle是通过onResume来通知可见性的,那这里就是缺少了一个fragment.isResumed()
但是仔细观察,并不是所有地方isResumed()都是管用的例如这里的isResumed()恒定是false 那么我们就要把isFragmentVisible分为isFragmentVisibleOnResume()isFragmentVisibleOnPause() 替换掉原来的isFragmentVisible()

补充:

可能我的描述不够直观,https://github.com/Ubitar/Fragmentation 还是show me the code 最好,我没有改Fragmentation的demo,仅仅修改了其core

疑问

1、怎么没有兼容setUserVisibleHint版本,直接跳setMaxLifecycle了?

额。我没有写,这个需要你看懂setMaxLifecycle的兼容后,再回去把旧的代码还原回来(onActivityCreatedisFragmentVisible之类),通过自己设置的Boolean值来控制是否兼容setMaxLifecycle





大哥,觉得可以的话Gayhub给个Star吧,他们是有交互效果的啊

相关文章

网友评论

      本文标题:Fragmentation如何兼容新版本的setMaxLifec

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