/**
* 对Fragment 扩展viewBindings方法
* 懒加载创建:
* 自动判断root View 已经创建了。
* 那么使用ViewBinding::bind方法
* 如果没有则使用ViewBinding::inflater方法
*
* 自动销毁:
* 监听生命周期onDestroyView事件,
* 把ViewBinding 置为 null
* 防止内存泄漏
*/@MainThreadinlinefun<reified T : ViewBinding> Fragment.viewBindings(crossinline viewBindingFactory:(View?)-> ViewBindingFactory<T>={//这做了下判断,如果当前Fragment已经有rootView了,那么就通过ViewBinding::bind的方法获取ViewBinding,反之则通过inflater方法实现if(it ==null)DefaultInflateViewBindingFactory(layoutInflater, T::class)elseDefaultBindViewBindingFactory(it, T::class)}): ReadOnlyProperty<Fragment, T>=object: ReadOnlyProperty<Fragment, T>{privatevar binding: T?=nullinit{
viewLifecycleOwnerLiveData.observe(this@viewBindings, Observer { viewLifecycleOwner ->
viewLifecycleOwner.lifecycle.addObserver(object: DefaultLifecycleObserver {//监听Fragment onDestroyViewoverridefunonDestroy(owner: LifecycleOwner){(binding as? ViewDataBinding)?.unbind()
binding =null
viewLifecycleOwner.lifecycle.removeObserver(this)}})})}overridefungetValue(thisRef: Fragment, property: KProperty<*>): T {
binding?.let{return it }// 操作ViewBinding 必须在onCreateView之后,所以给一个错误提示val viewLifecycleOwner =try{
thisRef.viewLifecycleOwner
}catch(e: IllegalStateException){error("Should not attempt to get bindings when Fragment views haven't been created yet. The fragment has not called onCreateView() at this point.")}//操作ViewBinding要在onDestroyView() super方法之前,不然提示错误if(!viewLifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)){error("Should not attempt to get bindings when Fragment views are destroyed. The fragment has already called onDestroyView() at this point.")}returnviewBindingFactory(thisRef.view).getViewBindings().also{ viewBinding ->if(viewBinding is ViewDataBinding){
viewBinding.lifecycleOwner = viewLifecycleOwner
}this.binding = viewBinding
}}}
ViewBindingFactory<ViewBinding> 是个什么东西
interface ViewBindingFactory<T: ViewBinding>{fungetViewBindings(): T
}// 通过inflate反射方法获取ViewBinding@Suppress("UNCHECKED_CAST")class DefaultInflateViewBindingFactory<T: ViewBinding>(layoutInflater: LayoutInflater, clazz: KClass<T>): ViewBindingFactory<T>{privateval vb: T = clazz.java.getMethod("inflate", LayoutInflater::class.java).invoke(null, layoutInflater)as T
overridefungetViewBindings(): T {return vb
}}// 通过bind反射方法获取ViewBinding@Suppress("UNCHECKED_CAST")class DefaultBindViewBindingFactory<T: ViewBinding>(view: View, clazz: KClass<T>): ViewBindingFactory<T>{privateval vb: T = clazz.java.getMethod("bind", View::class.java).invoke(null, view)as T
overridefungetViewBindings(): T {return vb
}}