Androidx ViewPager+Fragment 懒加载
轉載請標明出處:http://blog.csdn.net/zhaoyanjun6/article/details/113545036
本文出自【趙彥軍的博客】
目錄
- 前言
- 懶加載(預加載)
- 傳統模式
- Androidx
- 總結
前言
還有一個月就過年了,超級開心。
本文所有內容已經上傳至github:https://github.com/zyj1609wz/ViewPagerLazyLoad
懶加載(預加載)
懶加載字面意思就是當需要的時候才會去加載,不需要就不要加載。
以前處理 Fragment 的懶加載,我們通常會在 Fragment 中處理 setUserVisibleHint + onHiddenChanged 這兩個函數,而在 Androidx 模式下,我們可以使用 FragmentTransaction.setMaxLifecycle() 的方式來處理 Fragment 的懶加載。
fragment 生命周期:
onAttach -> onCreate -> onCreateView -> onViewCreated -> onActivityCreated -> onStart -> onResume
一般在 onCreate方法中接收 bundle 中的數據,在 onCreateView 創建 view初始化 布局。在 onActivityCreated或者 onResume做懶加載
傳統模式
package com.zhaoyanjun.mode1import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroupabstract class BaseFragment : Fragment() {/*** 用戶是否可見*/protected var mIsVisibleToUser = false/*** view是否創建*/protected var mIsViewCreated = false/*** 是否是第一次加載*/protected var mIsFirstLoad = falseoverride fun onActivityCreated(savedInstanceState: Bundle?) {super.onActivityCreated(savedInstanceState)mIsViewCreated = trueif (mIsVisibleToUser) {firstLoad()}}/*** 懶加載模式下生效*/fun firstLoad() {if (mIsFirstLoad) {return}mIsFirstLoad = trueonFirstLoad()}/*** 懶加載的時候調用*/open fun onFirstLoad() {}override fun setUserVisibleHint(isVisibleToUser: Boolean) {super.setUserVisibleHint(isVisibleToUser)mIsVisibleToUser = isVisibleToUserif (mIsVisibleToUser && mIsViewCreated) {firstLoad()}}override fun onDestroyView() {mIsVisibleToUser = falsemIsViewCreated = falsemIsFirstLoad = falsesuper.onDestroyView()} }使用 :
package com.zhaoyanjun.mode1import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import com.zhaoyanjun.Rclass ContentFragment : BaseFragment() {private var param1: String? = nullprivate var rootView: View? = nullprivate var nameTv: TextView? = nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)arguments?.let {param1 = it.getString(ARG_PARAM1)}}override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {rootView = inflater.inflate(R.layout.fragment_content, container, false)nameTv = rootView?.findViewById(R.id.name)return rootView}//懶加載更新數據override fun onFirstLoad() {super.onFirstLoad()//第一次加載Log.d("zhaoyanjun-", "firstLoad index: $param1")nameTv?.text = param1}companion object {private const val ARG_PARAM1 = "param1"@JvmStaticfun newInstance(param1: String) =ContentFragment().apply {arguments = Bundle().apply {putString(ARG_PARAM1, param1)}}} }Androidx
在使用 Androidx 的時候,會發現 FragmentPagerAdapter(fragmentManager) 方法過時了
取而代之的是 兩個參數的構造函數 。
mBehavior 有兩個值:BEHAVIOR_SET_USER_VISIBLE_HINT 、BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT 。 默認情況下使用的是 BEHAVIOR_SET_USER_VISIBLE_HINT
從官方的注釋聲明中,我們能得到如下兩條結論:
- 如果 behavior 的值為 BEHAVIOR_SET_USER_VISIBLE_HINT,那么當 Fragment 對用戶的可見狀態發生改變時,setUserVisibleHint 方法會被調用。
- 如果 behavior 的值為 BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT ,那么當前選中的 Fragment在 Lifecycle.State#RESUMED 狀態 ,其他不可見的 Fragment 會被限制在Lifecycle.State#STARTED 狀態。
所以我的的懶加載方案就呼之欲出了:
package com.zhaoyanjun.mode2import androidx.fragment.app.Fragmentabstract class BaseFragment2 : Fragment() {private var isLoaded = falseoverride fun onResume() {super.onResume()//增加了Fragment是否可見的判斷if (!isLoaded && !isHidden) {isLoaded = trueonFirstLoad()}}override fun onDestroyView() {super.onDestroyView()isLoaded = false}open fun onFirstLoad() {} }使用:
class ContentFragment2 : BaseFragment2() {private var param1: String? = nullprivate var rootView: View? = nullprivate var nameTv: TextView? = nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)arguments?.let {param1 = it.getString(ARG_PARAM1)}}override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {rootView = inflater.inflate(R.layout.fragment_content, container, false)nameTv = rootView?.findViewById(R.id.name)return rootView}override fun onFirstLoad() {super.onFirstLoad()//第一次加載Log.d("zhaoyanjun-mode2 ", "firstLoad index: $param1")nameTv?.text = param1}companion object {private const val ARG_PARAM1 = "param1"@JvmStaticfun newInstance(param1: String) =ContentFragment2().apply {arguments = Bundle().apply {putString(ARG_PARAM1, param1)}}}總結
本文代碼已上傳至:https://github.com/zyj1609wz/ViewPagerLazyLoad
總結
以上是生活随笔為你收集整理的Androidx ViewPager+Fragment 懒加载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 如何正确统计页面停留时长
- 下一篇: Kotlin实战指南十六:Synchro