通过委派机制和Kotlin的函数扩展,仿造viewModels 写一个viewBindings功能,辅助创建ViewBinding,同时在onDestroyView的回收ViewBinding
- 先看下怎么使用
class DemoFragment: Fragment(R.layout.fragment_demo) {
private val viewModels by activityViewModels<DemoViewModel>()
private val viewBindings by viewBindings<FragmentDemoBinding>()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewBindings...
}
}
- 看下怎么实现的。
Fragment.viewBindings<ViewBinding>()方法的实现
@MainThread
inline fun <reified T : ViewBinding> Fragment.viewBindings(
crossinline viewBindingFactory: (View?) -> ViewBindingFactory<T> = {
if(it == null) DefaultInflateViewBindingFactory(layoutInflater, T::class) else DefaultBindViewBindingFactory(it, T::class)
}
): ReadOnlyProperty<Fragment, T> = object : ReadOnlyProperty<Fragment, T> {
private var binding: T? = null
init {
viewLifecycleOwnerLiveData.observe(this@viewBindings, Observer { viewLifecycleOwner ->
viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onDestroy(owner: LifecycleOwner) {
(binding as? ViewDataBinding)?.unbind()
binding = null
viewLifecycleOwner.lifecycle.removeObserver(this)
}
})
})
}
override fun getValue(thisRef: Fragment, property: KProperty<*>): T {
binding?.let { return it }
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.")
}
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.")
}
return viewBindingFactory(thisRef.view).getViewBindings().also { viewBinding ->
if (viewBinding is ViewDataBinding) {
viewBinding.lifecycleOwner = viewLifecycleOwner
}
this.binding = viewBinding
}
}
}
ViewBindingFactory<ViewBinding> 是个什么东西
interface ViewBindingFactory<T: ViewBinding> {
fun getViewBindings(): T
}
@Suppress("UNCHECKED_CAST")
class DefaultInflateViewBindingFactory<T: ViewBinding>(layoutInflater: LayoutInflater, clazz: KClass<T>): ViewBindingFactory<T> {
private val vb: T = clazz.java.getMethod("inflate", LayoutInflater::class.java).invoke(null, layoutInflater) as T
override fun getViewBindings(): T {
return vb
}
}
@Suppress("UNCHECKED_CAST")
class DefaultBindViewBindingFactory<T: ViewBinding>(view: View, clazz: KClass<T>): ViewBindingFactory<T> {
private val vb: T = clazz.java.getMethod("bind", View::class.java).invoke(null, view) as T
override fun getViewBindings(): T {
return vb
}
}
- 逻辑的话,第一通过委派机制创建对象,之后再监听Fragment的生命周期的变化,把对象设置为null。如果要实现Activity这样的功能,代码类似。
|