@martin0207
2018-12-12T05:42:10.000000Z
字数 6472
阅读 1107
android
懒加载的作用上一篇中已经叙述过了,这篇拓展上一篇中:之所以费劲提取出来,是因为考虑到,已经成型的项目,替换BaseFragment类很费劲,我希望能够让Fragment只实现一个接口就可以实现这个功能。
牛皮吹出去了,总不能放着不管。这里仅需要:
即可实现懒加载功能。
想要实现前面说的,前提是需要知道:Activity可以通过supperFragmentManager
注册监听所拥有的Fragment的生命周期
/*
注册Fragment生命周期监听
*/
supportFragmentManager.registerFragmentLifecycleCallbacks(
//传入我们实现的类
FragmentLifecycleForLazyInitImpl(),
/*
是否递归Fragment中的Fragment
我们这里不做处理了
*/
false
)
说些我们知道的
LazyInitModel
supperFragmentManager
注册监听所拥有的Fragment的生命周期 setUserVisibleHint
调用时也需要判断是否需要调用懒加载方法 setUserVisibleHint
的方法 分析了这些条件,相信会有一些模糊的框架出来了,下面开始冻手
咱们先看看之前创建的全局变量
嗯~图片说的很对,咱就不多说了。
除了变量,我们需要设置修改是否对用户可见与当前生命周期的方法,并在方法调用时判断是否调用需要懒加载。
来来来,上代码:
open class LazyInitModel(val mLazyInitFragment: ILazyInitFragment) {
/**
* fragment的当前状态
* 用来控制lazyInit的调用
*/
var mCurrentState = ILazyInitFragment.ON_ATTACH
/**
* 调用lazyInit的状态判定
* 即mCurrentState>=getLazyInitState时,调用
* 这里设置为方法,是为了方便用户使用的时候,能够自定义该方法
*/
open fun getLazyInitState() = ILazyInitFragment.ON_ACTIVITY_CREATED
/**
* 是否已经初始化
*/
var mInitialized = false
/**
* 用户是否可见
*/
var mIsVisibleToUser = false
/**
* 设置当前是否对用户可见
*/
fun setUserVisibleHint(isVisibleToUser: Boolean) {
mIsVisibleToUser = isVisibleToUser
doLazyInit()
}
/**
* 设置当前生命周期
*/
fun setCurrentState(state: Int) {
mCurrentState = state
doLazyInit()
}
private fun doLazyInit() {
/*
若达到我们设置的状态条件,则调用方法
未初始化 且
用户可见 且
当前状态>= 懒加载触发状态
*/
if (!mInitialized && mIsVisibleToUser && mCurrentState >= getLazyInitState()) {
mLazyInitFragment.lazyInit()
mInitialized = true
}
}
}
model有了,我们需要通过接口获取该对象,所以需要在接口中添加获取model对象的方法:
interface ILazyInitFragment {
/**
* fragment的状态
* 延迟初始化一般都在这几种状态下(ATTACH除外)
* 所以只添加了这些状态
*/
companion object {
/**
* fragment依附于Activity(默认状态)
* 一般处于该状态下,不做任何操作
*/
const val ON_ATTACH = 0
const val ON_CREATED = 1
const val ON_CREATED_VIEW = 2
/**
* 推荐在下面两个状态下初始化
*/
const val ON_ACTIVITY_CREATED = 3
const val ON_RESUME = 4
}
/**
* 延迟初始化
*/
fun lazyInit() {}
/**
* 获取懒加载model
* 继承LazyInitFragment的不需要管该方法
* 是为了只实现接口功能而设立
*/
fun getLazyInitModel(): LazyInitModel? = null
}
这里将getLazyInitModel
设置可空并且设置默认值,是为了与上一篇的代码不冲突。
Fragment生命周期监听类需要继承FragmentManager.FragmentLifecycleCallbacks
,然后实现里面的各生命周期方法,现在我们只需要实现
至onFragmentResumed
以及onFragmentViewDestroyed
方法即可
/**
* Activity可以通过supportFragmentManager来注册监听Fragment的生命周期
* 因为只有生命周期的监听,而没有`setUserVisibleHint`方法监听
* 所以需要在Fragment中手动调用设置方法
*/
class FragmentLifecycleForLazyInitImpl : FragmentManager.FragmentLifecycleCallbacks() {
override fun onFragmentAttached(fm: FragmentManager, f: Fragment, context: Context) {
super.onFragmentAttached(fm, f, context)
setLifecycleState(f, ILazyInitFragment.ON_ATTACH)
}
override fun onFragmentCreated(fm: FragmentManager, f: Fragment, savedInstanceState: Bundle?) {
super.onFragmentCreated(fm, f, savedInstanceState)
setLifecycleState(f, ILazyInitFragment.ON_CREATED)
}
override fun onFragmentViewCreated(fm: FragmentManager, f: Fragment, v: View, savedInstanceState: Bundle?) {
super.onFragmentViewCreated(fm, f, v, savedInstanceState)
setLifecycleState(f, ILazyInitFragment.ON_CREATED_VIEW)
}
override fun onFragmentActivityCreated(fm: FragmentManager, f: Fragment, savedInstanceState: Bundle?) {
super.onFragmentActivityCreated(fm, f, savedInstanceState)
setLifecycleState(f, ILazyInitFragment.ON_ACTIVITY_CREATED)
}
override fun onFragmentResumed(fm: FragmentManager, f: Fragment) {
super.onFragmentResumed(fm, f)
setLifecycleState(f,ILazyInitFragment.ON_RESUME)
}
override fun onFragmentViewDestroyed(fm: FragmentManager, f: Fragment) {
super.onFragmentViewDestroyed(fm, f)
/**
* 这里是个小坑
* ViewPager的规则,默认会销毁当前Fragment及左右两个之外的Fragment视图。
* 即:滑到第3个Fragment时,第1个Fragment会被销毁视图,且只调用到这一步
*/
if (f is ILazyInitFragment) {
(f as ILazyInitFragment).getLazyInitModel()?.mInitialized = false
}
}
/**
* 设置生命周期状态
*/
private fun setLifecycleState(fragment: Fragment, state: Int) {
//首先判断是否已经实现 ILazyInitFragment 接口
if (fragment is ILazyInitFragment) {
(fragment as ILazyInitFragment).getLazyInitModel()?.setCurrentState(state)
}
}
}
前面准备的这么充分,后面就可以行的方便了。
class AchieveZeroFragment : Fragment(), ILazyInitFragment {
val TAG = this.javaClass.simpleName
/*
******************************************************************************************************
* 使用开始
******************************************************************************************************
*/
private var mLazyInitModel: LazyInitModel? = null
override fun getLazyInitModel(): LazyInitModel? {
if (mLazyInitModel == null)
mLazyInitModel = LazyInitModel(this)
/*
还可以自定义LazyInitModel
*/
// mLazyInitModel = CustomLazyInitModel(this)
return mLazyInitModel
}
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
//无法监听到这个方法,需要手动调用
getLazyInitModel()?.setUserVisibleHint(isVisibleToUser)
}
override fun lazyInit() {
/*
可以在该方法内调用需要懒加载的方法
*/
tv_msg.text = TAG
Timber.e("$TAG 初始化")
}
/*
******************************************************************************************************
* 使用结束
******************************************************************************************************
*/
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_common, container, false)
}
}
class AchieveActivity : AppCompatActivity() {
val mAdapter = CommonFragmentPagerAdapter(
supportFragmentManager, arrayListOf(
AchieveZeroFragment(),
AchieveOneFragment(),
AchieveTwoFragment(),
AchieveThreeFragment()
)
)
val mLifecycleForLazyInitImpl = FragmentLifecycleForLazyInitImpl()
companion object {
fun start(context: Context) {
val intent = Intent(context, AchieveActivity::class.java)
context.startActivity(intent)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_achieve)
/*
注册Fragment生命周期监听
*/
supportFragmentManager.registerFragmentLifecycleCallbacks(
//传入我们实现的类
mLifecycleForLazyInitImpl,
/*
是否递归Fragment中的Fragment
我们这里不做处理了
*/
false
)
supportFragmentManager.registerFragmentLifecycleCallbacks(FragmentLifecycleForLazyInitImpl(), false)
vp.adapter = mAdapter
}
override fun onDestroy() {
super.onDestroy()
supportFragmentManager.unregisterFragmentLifecycleCallbacks(mLifecycleForLazyInitImpl)
}
}
哎~怎么添加这么多行代码?
别闹了~注释不能算吧,分行写不也是为了注释的清楚嘛!
//创建对象
val mLifecycleForLazyInitImpl = FragmentLifecycleForLazyInitImpl()
//注册
supportFragmentManager.registerFragmentLifecycleCallbacks(FragmentLifecycleForLazyInitImpl(), false)
//反注册
supportFragmentManager.unregisterFragmentLifecycleCallbacks(FragmentLifecycleForLazyInitImpl())
这样子就是3行了吧~