本篇将讲述Fragment懒加载的使用
Fragment懒加载
本篇已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的适配器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class 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的类来进行懒加载
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
51abstract 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方法,才可以进行加载数据