Android ViewPager2 setOffscreenPageLimit预加载Fragment,Kotlin

Android ViewPager2 setOffscreenPageLimit预加载Fragment,Kotlin

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2


class MainActivity : AppCompatActivity() {
    companion object {
        const val TAG = "fly"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val mViewPager2 = findViewById<ViewPager2>(R.id.vp2)
        mViewPager2.adapter = MyPageAdapter(this)
    }

    class MyPageAdapter : FragmentStateAdapter {
        private var mFragments = arrayListOf<MyFragment>()

        constructor(activity: FragmentActivity) : super(activity) {
            for (i in 0 until 5) {
                mFragments.add(MyFragment(i))
            }
        }

        override fun getItemCount(): Int {
            return mFragments.size
        }

        override fun createFragment(position: Int): Fragment {
            return mFragments[position]
        }
    }

    class MyFragment : Fragment {
        private var seq = 0

        constructor(seq: Int) {
            this.seq = seq
            Log.d(TAG, "$seq constructor")
        }

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            Log.d(TAG, "$seq onCreate")
        }

        override fun onResume() {
            super.onResume()
            Log.d(TAG, "$seq onResume")
        }

        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            return inflater.inflate(android.R.layout.simple_list_item_1, container, false)
        }

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            val tv = view.findViewById<TextView>(android.R.id.text1)
            tv.text = "$seq"
            tv.textSize = 50f
            Log.d(TAG, "$seq onViewCreated")
        }

        override fun onPause() {
            super.onPause()
            Log.d(TAG, "$seq onPause")
        }

        override fun onDestroy() {
            super.onDestroy()
            Log.d(TAG, "$seq onDestroy")
        }

        override fun onDestroyView() {
            super.onDestroyView()
            Log.d(TAG, "$seq onDestroyView")
        }
    }
}

ViewPager2与ViewPager不同,默认情况下,由于ViewPager2内部源代码中mOffscreenPageLimit默认等于-1:

    public static final int OFFSCREEN_PAGE_LIMIT_DEFAULT = -1;

所以,当ViewPager2装载好Fragment启动后,只会显示当前可见的那1个Fragment,而不像过去的ViewPager那样,把后面不可见的Fragment也加载出来:

0 constructor
1 constructor
2 constructor
3 constructor
4 constructor
0 onCreate
0 onViewCreated
0 onResume

日志显示,只加载了当前可见的0号Fragment,没有加载1号Fragment。

此时,往左滑,使得1号Fragment显示在屏幕:

1 onCreate
1 onViewCreated
0 onPause
1 onResume

Fragment 1此时才创建,没有加载不可见的2号Fragment。

简单的说,这就是过去VIewPager时代,想要实现的“懒加载”模式:让ViewPager只加载当前可见的那个Fragment。而在ViewPager2中,默认情况不设置

mOffscreenPageLimit

时候,ViewPager2就是懒加载模式的ViewPager标准实现,只会加载当前显示的那1个Fragment,不会加载后面不可见的Fragment。


如果,设置了mOffscreenPageLimit呢?给mOffscreenPageLimit设置0或者-1?看看ViewPager2中的setOffscreenPageLimit()源代码:

    public void setOffscreenPageLimit(@OffscreenPageLimit int limit) {
        if (limit < 1 && limit != OFFSCREEN_PAGE_LIMIT_DEFAULT) {
            throw new IllegalArgumentException(
                    "Offscreen page limit must be OFFSCREEN_PAGE_LIMIT_DEFAULT or a number > 0");
        }
        mOffscreenPageLimit = limit;
        // Trigger layout so prefetch happens through getExtraLayoutSize()
        mRecyclerView.requestLayout();
    }

已知的是OFFSCREEN_PAGE_LIMIT_DEFAULT=-1。从源代码可以看到,ViewPager2的setOffscreenPageLimit()只接受 >= 1的值,看来不能给mOffscreenPageLimit设置0或者-1。

现在给ViewPager2的设置1:

mViewPager2.offscreenPageLimit = 1

重新编译,看看启动后装载Fragment的表现:

0 constructor
1 constructor
2 constructor
3 constructor
4 constructor
0 onCreate
0 onViewCreated
0 onResume
1 onCreate
1 onViewCreated

除了加载当前可见的0号Fragment外,ViewPager2也把不可见的、后面1号Fragment顺带加载出来了,这和过去老版ViewPager相同。

往左滑一个页面,把1号Fragment显示出来当前可见:

2 onCreate
2 onViewCreated
0 onPause
1 onResume

调用了1号Fragment的onResume周期方法,并把不可见的2号Fragment创建出来。

如果offscreenPageLimit 是2:

mViewPager2.offscreenPageLimit = 2

编译重新启动后:

0 constructor
1 constructor
2 constructor
3 constructor
4 constructor
0 onCreate
0 onViewCreated
0 onResume
1 onCreate
1 onViewCreated
2 onCreate
2 onViewCreated

除了把当前可见的0号Fragment加载出来外,还把不可见的1号和2号Fragment也加载出来了。


总结:

1、ViewPager2默认不设置mOffscreenPageLimit情况下,就是过去老版ViewPager想要达到的“懒加载”“延迟加载”模式,即,只加载当前可见的那1个Fragment。

2、如果设置了mOffscreenPageLimit(并且,mOffscreenPageLimit通过setOffscreenPageLimit()这个API接口也只能设置  >=1 的值),ViewPager2就退化成过去老版的ViewPager了,除了把当前可见的那个Fragment加载出来外,还会根据用户设置的mOffscreenPageLimit值,加载mOffscreenPageLimit个不可见的Fragment。即一次性总共加载 1 + mOffscreenPageLimit 个Fragment。1是当前屏幕显示的那1个Fragment;mOffscreenPageLimit是后面不可见的Fragment。

ViewPager2和Fragment可见性及懒加载解决方案_viewpage2和fragment 当前页面可见接受消息-CSDN博客文章浏览阅读6.5k次,点赞5次,收藏14次。ViewPager2和Fragment新的可见性及懒加载解决方案,旨在解决ViewPager(ViewPager2)只有当前Fragment唯一可见时候网络刷新或绘图。注意:过去的setUserVisibleHint()已被废弃,开发者不要再使用基于setUserVisibleHint()解决Fragment可见性和懒加载(或延迟加载)的场景。新方案用最新的ViewPager2替代过去旧版的ViewPager,再结合Fragment的resume和pause生命周期实现。写一个demo例子,测试的主类M_viewpage2和fragment 当前页面可见接受消息https://blog.csdn.net/zhangphil/article/details/108893237Android ViewPager2 load once when fast scroll many page,Java-CSDN博客文章浏览阅读206次。ViewPager2和Fragment新的可见性及懒加载解决方案,旨在解决ViewPager(ViewPager2)只有当前Fragment唯一可见时候网络刷新或绘图。注意:过去的setUserVisibleHint()已被废弃,开发者不要再使用基于setUserVisibleHint()解决Fragment可见性和懒加载(或延迟加载)的场景。新方案用最新的ViewPager2替代过去旧版的ViewPager,再结合Fragment的resume和pause生命周期实现。写一个demo例子,测试的主类M。https://blog.csdn.net/zhangphil/article/details/129885331Android ViewPager2嵌套RecyclerView性能优化RecycledViewPool,kotlin-CSDN博客文章浏览阅读750次。ViewPager2和Fragment新的可见性及懒加载解决方案,旨在解决ViewPager(ViewPager2)只有当前Fragment唯一可见时候网络刷新或绘图。注意:过去的setUserVisibleHint()已被废弃,开发者不要再使用基于setUserVisibleHint()解决Fragment可见性和懒加载(或延迟加载)的场景。ViewPager2和Fragment可见性及懒加载解决方案_viewpager2 懒加载_zhangphil的博客-CSDN博客。_viewpager2嵌套recyclerviewhttps://blog.csdn.net/zhangphil/article/details/131231747

相关推荐

  1. vue图片

    2024-03-28 08:06:04       36 阅读
  2. android 进程

    2024-03-28 08:06:04       29 阅读
  3. 同步、异步、延迟的区别

    2024-03-28 08:06:04       64 阅读
  4. 前端图片和懒

    2024-03-28 08:06:04       38 阅读
  5. 编程思想:与懒

    2024-03-28 08:06:04       28 阅读
  6. Keras训练模型

    2024-03-28 08:06:04       62 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-28 08:06:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-28 08:06:04       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-28 08:06:04       82 阅读
  4. Python语言-面向对象

    2024-03-28 08:06:04       91 阅读

热门阅读

  1. C#WPF控件Label宽度绑定到父控件的宽度

    2024-03-28 08:06:04       35 阅读
  2. C++入门

    C++入门

    2024-03-28 08:06:04      37 阅读
  3. 用WHERE命令可以在命令行搜索文件

    2024-03-28 08:06:04       34 阅读
  4. 【Kotlin】Array简介

    2024-03-28 08:06:04       42 阅读
  5. Spring MVC Thymeleaf在一个表单中的多个提交按钮

    2024-03-28 08:06:04       44 阅读
  6. Kafka高级面试题-2024

    2024-03-28 08:06:04       43 阅读
  7. 什么是高阶组件,有哪些场景?

    2024-03-28 08:06:04       46 阅读
  8. PHP中常见的CRUD函数

    2024-03-28 08:06:04       43 阅读