首页 > 其他分享 >Android模仿微博的LazyFragment懒加载

Android模仿微博的LazyFragment懒加载

时间:2023-06-22 14:32:06浏览次数:40  
标签:setUserVisibleHint 分发 Fragment LazyFragment 可见 微博 Android 数据 加载


本文会从头开始一步一步带你去写一个LazyFragment,根据写的过程中一步一步记录,你也可以自己试一试,跟着一起写写。最后也根据遇到的问题去完善了,网上搜的都是不完善的,还是自己写一个吧!

懒加载是在加载啥?

这个问题显得很愚蠢。但是想一下,懒加载到底是加载数据和视图,还是数据呢??(一开始我也想过这个问题。。。)当然是数据啦,你怎么能阻止视图的加载呢!你是无法阻止Fragment的生命周期函数的执行的,所以只能让当前显示的Fragment加载数据,不显示不加载数据

怎么能知道当前页面是显示的这个Fragment呢?

在源码中有两个方法可以使用

在viewpager和fragment模式使用的
public void setUserVisibleHint(boolean isVisibleToUser) {}

在add+show+hide模式使用
public void onHiddenChanged(boolean hidden) {}

那么就先简单的试试看这两个方法好了 我写了一个Viewpager+Fragment模式的,缓存数量offscreenPageLimit为1

当打开app时

我们可以看到主页BadHomeFragmentsetUserVisibleHint()方法执行了两次!先返回false不可见,再返回true可见。而且不管在哪个Fragment中setUserVisibleHint()都跑得比生命周期快

Android模仿微博的LazyFragment懒加载_apache

当切换到第二个Fragment

Android模仿微博的LazyFragment懒加载_apache_02

切回去主页Fragment

当已经跑过生命流程的Fragment再次显示时,只会走setUserVisibleHint()(先忽略onHiddenChange方法)

Android模仿微博的LazyFragment懒加载_android_03

这样的话,我们大概可以想到,我根据setUserVisibleHint()的可见状态去加载数据不就完事了吗?

所以我们先这样写

Android模仿微博的LazyFragment懒加载_java_04

在子Fragment中的loadData中调用接口获取数据,然后给控件赋值

Android模仿微博的LazyFragment懒加载_加载数据_05

结果就是!报错!!说你的控件为null,我都可见了为啥为null呢。因为在进入app时setUserVisibleHint在生命周期前面,Fragment都没有加载布局,当然为null啦

Android模仿微博的LazyFragment懒加载_android_06

那我加个变量判断一下布局有没有加载好不就行了?

Android模仿微博的LazyFragment懒加载_加载_07

结果呢?主页Fragment没有执行onLoadData方法,点击TwoFragment却执行了,为什么呢,因为setUserVisibleHint更早啊,而TwoFragment已经初始化过了,点击过去的时候才能正常加载数据。

Android模仿微博的LazyFragment懒加载_apache_08

所以我们必须在生命周期中再分发一次加载数据的事件,把加载数据提成一个方法

Android模仿微博的LazyFragment懒加载_apache_09

再来看看从开启app到点击到第三个Fragment的日志,大家都正常的加载了数据,好像还挺正常的

Android模仿微博的LazyFragment懒加载_加载数据_10

那再试试从第一个页面跳转到最后一个页面吧,会发现中间有些页面莫名的就调用了StopLoadData函数???这显然有问题的,看来不能只是简单的用可见状态来分发了

Android模仿微博的LazyFragment懒加载_apache_11

我们在好好想一下,LoadData是Fragment可见的时候调用, StopLoadData是Fragment不可见的时候调用。其实这样说并不完全,应该是从不可见状态到可见状态的时候加载数据,可见状态到不可见状态的时候停止。所以我们得用一个变量记录一下可见状态

Android模仿微博的LazyFragment懒加载_android_12

可以看到在切换方面,分发的事件已经是正常的了 注意要在onStopcurrentVisibleStatus状态重置!

Android模仿微博的LazyFragment懒加载_加载数据_13

以上就是我们网上常见的懒加载了,但是会有两个问题

在跳转到其他页面回来时,会怎么样?

并不会怎样,只是回来的时候不会去分发加载数据的事件而已啧 所以我加上这样一段代码,用一个变量去判断,不需要可以不写,但是我想想你跳转了别的页面,回来数据Fragment数据应该会变,所以分发一下

Android模仿微博的LazyFragment懒加载_apache_14

在子Fragment中又有一个viewpager+Fragment又会怎么样?

这里去除掉了其他log,为了看起来清楚点

我给TowFragment加了一个viewpager,里面有TowFragment1和2

进入App可以看到,爹都还没显示,儿子先加载了数据?

Android模仿微博的LazyFragment懒加载_android_15

而且在之后的切换底部Tab,TowFragment里面的两个儿子都无动于衷,只有刚打开App时加载了,连停止加载的方法都没调用到,根本就没有事件分发到儿子那里去

Android模仿微博的LazyFragment懒加载_android_16

所以我们必须要再做一些根据父亲和儿子的状态再做一些判断 先解决第一个问题,父Fragment还没显示,子Fragment就加载了数据。这个问题很简单,我们只需要在分发加载数据的事件时,判断一下是否有父Fragment,且是否可见。就可以了

根据Fragment源码中的这个方法,可以解决上面的问题

Android模仿微博的LazyFragment懒加载_加载_17

比如,父Fragment不可见时直接退出方法,不准分发

Android模仿微博的LazyFragment懒加载_java_18

但是还有一个问题存在,就是不管怎么切换,子Fragment都不会分发加载或停止加载数据的事件。这是为啥??

从一开始我们可以看到,在进入HomeFragment时,子Fragment也会分别调用两次setUserVisibleHint方法,在进入前就把自己的可见状态置为true。到底后面的分发事件无效了。

所以我决定在进入他的父Fragment时,再去调用一次分发事件,真正的加载子Fragment的数据,比如

Android模仿微博的LazyFragment懒加载_apache_19

可以看见切换都是正常的

Android模仿微博的LazyFragment懒加载_java_20

最后到这里这个懒加载的写作思路就这样结束了~ 接下来就是加上SmartRefresh控件去模仿微博的加载模式了(当然只能简陋的模仿),有空会补上的!


标签:setUserVisibleHint,分发,Fragment,LazyFragment,可见,微博,Android,数据,加载
From: https://blog.51cto.com/u_16163510/6534881

相关文章

  • 【干货分享】全套Android学习笔记+最新大厂面试真题合集,打包领取
    笔者是一名普通的软件开发人员,一向不喜欢高高在上或者晦涩难懂的理论。我认为知识的本身也应该是通俗易懂的,用晦涩难懂的东西去描述,是对人类进步的阻碍,是知识垄断。笔者希望此系列教程能够以工程实现为出发点和落脚点,简化理论知识,化繁为简地解析Android相关知识点,为各位读者成长为......
  • 【Android】iOS开发中xconfig和script脚本的使用
    利用Xcode进行开发时需要进行很多buildsetting的设置以便能让项目按照设置的进行编译,同时有时候需要在编译时利用script脚本进行一些设置,本文主要介绍xconfig文件和script脚本在Xcode开发中使用。作者:MambaYongXcode编译在使用xconfig时有几个关于Xcode的概念是需要理解的,这里我进......
  • Android AIDL 跨进程通信超详版
    来了新公司,公司项目里用了很多的独立进程的服务与他们之间存在了很多跨进程的通信。之前有很长一段时间没有实际去做跨进程通信AIDL了,查阅了一些资料和文章看了些Demo把温习的心路历程介绍一下。来模拟一个ktv播控系统(client)控制大屏上的歌曲的播放、暂停动作KtvAIDLClientK......
  • Android13(T) 的Target适配问题总结
    最近在做Android13(T)的Target适配,整理了适配过程中遇到的问题分以下三部分:影响所有应用的变更(包含target33),只影响TargetSdkVersion=33的变更,其他更改(新增或者改善的功能).1.影响所有应用的变更1.1必须要适配此项1.1.1通知的运行时权限Android13中引入了一种新的......
  • Android app的启动优化总结
    工欲善其事必先利其器,最近在启动优化上踩了不少坑,写篇文章记录下,也给大伙避避坑,节省些时间。启动优化是什么,完全可以顾名思义,本文就不赘述了。至于为什么要做性能优化–QAQ,大家dddd问题场景主要分为如下两种场景,笔者主要在第一种场景下进行实操哈1、项目中已有性能启动相关埋点以及......
  • 95后Android开发:“我现在是真想躺平...“
    我是真想躺平…说实话,我现在每天上班都很难受,我也不知道为啥反正就很丧,很想当一条咸鱼,就想躺着。最近疫情、裁员…坏消息很多,大环境不好,我本就打算今年换工作的,现在这环境就有点烦…其他行业可能不知道,程序员跳槽最佳的时间就是3-4月,或者9-10月,被称为金三银四和金九银十,但是今年这......
  • 【工程化】Android开发电脑中都装了哪些软件
    写在前面工欲善其事,必先利其器。作为一名Android开发者,在开始正式开发之前,给电脑安装各种开发相关软件是必不可少的。今天来罗列下我电脑中装的那些开发相关的软件,一来换新电脑时,可以方便根据应用清单安装软件,二来如果你是刚从事Android开发,也可以参考着安装这些软件,希望可以帮助到......
  • Framework有多重要?Android framework 深层解读
    前言时间已经到了六月份了,这段时间整理了一下自打当公司Android面试官以来的奇葩事情,这才发现这奇葩事可真是多,跟另外一个HR朋友聊天,他说前段时间面一个Android高级架构,最后和他差点干起来了…我问他为什么,面个试还这么惊险刺激,差点挨上一顿打,真被打了那算工伤,公司指定得给你报销药......
  • AndroidUI进阶-为什么不能在子线程更新UI
    为什么不能在子线程更新UIandroid.view.ViewRootImpl$CalledFromWrongThreadException:Onlytheoriginalthreadthatcreatedaviewhierarchycantouchitsviews.atandroid.view.ViewRootImpl.checkThread(ViewRootImpl.java:8798)atandroid.view.ViewR......
  • 这应该是堪称教科书级别的“Android Framework学习笔记”了,字节九位大佬联合打造,首次
    相信大家在找工作的时候,肯定或多或少都被面试官问到过安卓的八股文。ActivityManagerService(简称AMS),或者WindowManagerService(WMS)怎么实现的啊,有些什么细节需要注意啊,View被加入到ViewRoot的流程啊等等。在我看来,对于应用开发来说,面试考这些纯粹就是扯淡,很有可能面试官自己也......