@martin0207
2018-12-12T05:42:10.000000Z
字数 6472
阅读 1157
android

懒加载的作用上一篇中已经叙述过了,这篇拓展上一篇中:之所以费劲提取出来,是因为考虑到,已经成型的项目,替换BaseFragment类很费劲,我希望能够让Fragment只实现一个接口就可以实现这个功能。
牛皮吹出去了,总不能放着不管。这里仅需要:
即可实现懒加载功能。
想要实现前面说的,前提是需要知道:Activity可以通过supperFragmentManager注册监听所拥有的Fragment的生命周期
/*注册Fragment生命周期监听*/supportFragmentManager.registerFragmentLifecycleCallbacks(//传入我们实现的类FragmentLifecycleForLazyInitImpl(),/*是否递归Fragment中的Fragment我们这里不做处理了*/false)
说些我们知道的
LazyInitModelsupperFragmentManager注册监听所拥有的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 = isVisibleToUserdoLazyInit()}/*** 设置当前生命周期*/fun setCurrentState(state: Int) {mCurrentState = statedoLazyInit()}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 = 0const val ON_CREATED = 1const val ON_CREATED_VIEW = 2/*** 推荐在下面两个状态下初始化*/const val ON_ACTIVITY_CREATED = 3const 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? = nulloverride 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 = TAGTimber.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行了吧~