Fragment懒加载

本篇将讲述Fragment懒加载的使用

Fragment懒加载

本篇已Kotlin为主要语言

介绍:懒加载就顾名思义,也就是当前Fragment处于可见的状态时,才会去进行加载,这种情况很适合Fragment嵌套Fragment,下面介绍原因

  • Activity嵌套Fragment:

image-20201228152427313

这样当Activity进行创建完Fragment时,这3个Fragment都会运行,执行他们的生命周期。

  • Activity嵌套Fragment嵌套Fragment:

image-20201228152443555

这种情况下,但Fragment_1进行添加并创建Fragment_a,Fragment_b,Fragment_c时,Fragment_b中又会继续创建Fragment_d,Fragment_e,Fragment_f,所以这样会在很多不可见的Fragment中浪费内存和网络。

因此我们想要进行Fragment懒加载,只让处于显示状态的Fragment进行加载。

  • Activity嵌套ViewPager嵌套Fragment

image-20201228153209898

观察上图,我们能发现 ViePager 初始化时,默认会调用其内部 Fragment 的 setUserVisibleHint 方法,因为其预缓存 Fragment 个数为 1 的原因,所以只有 Fragment_1 与 Fragment_2 的生命周期函数被调用。

ViewPager+Fragment模式下的懒加载

在Andoirdx中,之前的setUserVisibleHint 已经无法使用,现在只需要给适配器传递BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT即可,这样,Fragment在重复创建时,则会调用onResume方法

  1. 创建ViewPager的适配器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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 方法。

  2. 之后还需要创建一个继承Fragment的类来进行懒加载

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    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方法,才可以进行加载数据

ViewPager2+Fragment模式下的懒加载