实现ViewPager和ViewPager2的Fragment懒加载
本文介绍ViewPager和ViewPager2的懒加载如何实现,不谈为什么要懒加载。使用Kotlin代码。
ViewPager和ViewPager2都是继承与ViewGroup类,且运用方式大同小异,但也有一些差异。
由于ViewPager一直都有迭代,文章开始前,这里先抛出开发环境:
Android Stdio Bumblebee plugins { id 'com.android.application' version '7.1.3' apply false id 'com.android.library' version '7.1.3' apply false id 'org.jetbrains.kotlin.android' version '1.6.21' apply false } android { ... defaultConfig { ... minSdk 26 targetSdk 32 ... } ... }
ViewPager+Fragment需要使用 FragmentStatePagerAdapter 适配器,而ViewPager2+Fragment需要使用FragmentStateAdapter 适配器。文章前半部分先介绍ViewPager+Fragment的懒加载实现,后半部分介绍ViewPager2+Fragment的。目前SDK32的androidx环境已集成ViewPager、ViewPager2相关内容,本文中提到的也是用的这些。
ViewPager+Fragment的懒加载实现
实际上是3部分:ViewPager | Fragment | FragmentStatePagerAdapter
但我们需要操刀的只有Fragment 和 FragmentStatePagerAdapter
继承于Fragment的Base类,载入适配器的Fragment必须继承于此类:
abstract class ViewPagerFragmentLazy : Fragment() { private var rootView: View? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? {
rootView = createView(inflater, container, savedInstanceState)
return rootView
}
abstract fun createView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View override fun onResume() { super.onResume( lazyLoad(rootView!!) } override fun onPause() { super.onPause() stopLoad() }
// 加载你的内容 abstract fun lazyLoad(view: View)
// 当页面被划出,或者Fragment被遮挡,停止加载(简单的说,看不到了就停止) abstract fun stopLoad() }
适配器类:
class ViewPagerFragmentAdapter( fm: FragmentManager, var fragmentTitles: MutableList<String>? = null, var fragments: MutableList<Fragment>? = null) : FragmentStatePagerAdapter(fm, FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { init { if (null == fragmentTitles || null == fragments) { useDefaultTestData() } } private fun useDefaultTestData() { if (null == fragmentTitles) { // 标题 fragmentTitles = arrayListOf("1", "2", "3", "4", "5") } if (null == fragments) { // Fragment extender ViewPagerFragmentLazy fragments = ArrayList<Fragment>(fragmentTitles!!.size) fragments?.add(HomeFragment2()) fragments?.add(DashboardFragment()) fragments?.add(NotificationsFragment()) fragments?.add(HomeFragment2()) fragments?.add(HomeFragment2()) } } override fun getCount(): Int { return if (fragmentTitles!!.size == fragments!!.size) { fragments!!.size } else { 0 } } // 获取标题 fun getItemTitle(position: Int): String { return fragmentTitles!![position] } override fun getItem(position: Int): Fragment { return fragments!![position] } override fun getItemPosition(`object`: Any): Int { return POSITION_NONE } }
Activity中实现:
class MainActivity2 : FragmentActivity() { private lateinit var bindingTest2: LayoutViewpagerTest2Binding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) test2() } fun test2() { bindingTest2 = LayoutViewpagerTest2Binding.inflate(layoutInflater) setContentView(bindingTest2.root) val viewPager = bindingTest2.viewPager viewPager.adapter = ViewPagerFragmentAdapter(supportFragmentManager)
} }
ViewPager2+Fragment的懒加载实现
需要操刀的只有Fragment 和 FragmentStateAdapter
继承于Fragment的Base类,载入适配器的Fragment必须继承于此类:
abstract class Test1ViewPager2FragmentLazy : Fragment() { private var rootView: View? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { rootView = createView(inflater, container, savedInstanceState) return rootView } override fun onResume() { super.onResume() lazyLoad(rootView!!) } override fun onPause() { super.onPause() stopLoad() } abstract fun createView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View abstract fun lazyLoad(view: View) abstract fun stopLoad() }
适配器类:
class Test1ViewPager2FragmentAdapter(private val fragmentActivity: FragmentActivity) : FragmentStateAdapter(fragmentActivity) { private val fragments : SparseArray<Fragment> = SparseArray() init { fragments.put(PAGE_HOME, HomeFragment()) fragments.put(PAGE_DASHBOARD, DashboardFragment()) fragments.put(PAGE_NOTIFICATIONS, NotificationsFragment()) fragments.put(PAGE_OTHER1, HomeFragment()) fragments.put(PAGE_OTHER2, HomeFragment()) } companion object { const val PAGE_HOME = 0 const val PAGE_DASHBOARD = 1 const val PAGE_NOTIFICATIONS = 2 const val PAGE_OTHER1 = 3 const val PAGE_OTHER2 = 4 } override fun getItemCount(): Int { return fragments.size() } override fun createFragment(position: Int): Fragment { return fragments[position] } }
Activity中实现:
class MainActivity2 : FragmentActivity() { private lateinit var bindingTest1: LayoutViewpagerTest1Binding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) test1() } private fun test1() { bindingTest1 = LayoutViewpagerTest1Binding.inflate(layoutInflater) setContentView(bindingTest1.root) val viewPager2 = bindingTest1.viewPager val adapter = Test1ViewPager2FragmentAdapter(this) viewPager2.adapter = adapter viewPager2.offscreenPageLimit = 1 } }
总结
从以上代码中可以发现,SDK32中的ViewPager和ViewPager2的加载器有所不同,但是懒加载的 Base Fragmen 已经一样了!!
同时,因为已经使用了Lifecycle来管理Fragment的生命周期,所以,嵌套的问题,不存在

浙公网安备 33010602011771号