Fragment懒加载
这是我的Github地址:https://github.com/brokes6
我的博客:https://brokes6.github.io/
本篇已Kotlin为主要语言
介绍:懒加载就顾名思义,也就是当前Fragment处于可见的状态时,才会去进行加载,这种情况很适合Fragment嵌套Fragment,下面介绍原因
- Activity嵌套Fragment:
这样当Activity进行创建完Fragment时,这3个Fragment都会运行,执行他们的生命周期。
- Activity嵌套Fragment嵌套Fragment:
这种情况下,但Fragment_1进行添加并创建Fragment_a,Fragment_b,Fragment_c时,Fragment_b中又会继续创建Fragment_d,Fragment_e,Fragment_f,所以这样会在很多不可见的Fragment中浪费内存和网络。
因此我们想要进行Fragment懒加载,只让处于显示状态的Fragment进行加载。
- Activity嵌套ViewPager嵌套Fragment
观察上图,我们能发现 ViePager 初始化时,默认会调用其内部 Fragment 的 setUserVisibleHint 方法,因为其预缓存 Fragment 个数为
1
的原因,所以只有 Fragment_1 与 Fragment_2 的生命周期函数被调用。
ViewPager+Fragment模式下的懒加载
在Andoirdx中,之前的setUserVisibleHint 已经无法使用,现在只需要给适配器传递BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT即可,这样,Fragment在重复创建时,则会调用onResume方法
-
创建ViewPager的适配器
class ViewPagerAdapter( fm: FragmentManager, private val titles: MutableList<String>, private val fragments: MutableList<Fragment> ) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { override fun getCount(): Int { fragments.size } override fun getItem(position: Int): Fragment { return fragments[position] } override fun getPageTitle(position: Int): CharSequence? { return titles[position] } }
传入3个参数,一个是Fragment管理器,Fragment集合,Fragment标题,然后将behavior值设置为"BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT"
使用了
BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT
后,只有当前可见的 Fragment 才能调用 onResume 方法。 -
之后还需要创建一个继承Fragment的类来进行懒加载
abstract class BaseFragment : Fragment() { /** * 是否执行懒加载 */ private var isLoaded = false private var mView: View? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { if (mView == null) { mView = initView(inflater, container, savedInstanceState) } return mView } abstract fun initView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View abstract fun initData() override fun setUserVisibleHint(isVisibleToUser: Boolean) { super.setUserVisibleHint(isVisibleToUser) this.isVisibleUser = isVisibleToUser lazyLoad() } override fun onResume() { super.onResume() //增加了Fragment是否可见的判断 if (!isLoaded && !isHidden) { initData() isLoaded = true } } //在Fragment销毁View的时候,重置状态 override fun onDestroyView() { super.onDestroyView() isLoaded = false } }
这样,只有处于可见状态下的Fragment才能触发onResume方法,才可以进行加载数据