我是靠谱客的博主 繁荣钻石,这篇文章主要介绍Kotlin 委派(ReadOnlyProperty) 仿造viewModels 写一个viewBindings通过委派机制和Kotlin的函数扩展,仿造viewModels 写一个viewBindings功能,辅助创建ViewBinding,同时在onDestroyView的回收ViewBinding,现在分享给大家,希望可以做个参考。

通过委派机制和Kotlin的函数扩展,仿造viewModels 写一个viewBindings功能,辅助创建ViewBinding,同时在onDestroyView的回收ViewBinding

  1. 先看下怎么使用
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 一个简陋的MVP // DemoFragment 作为P的角色 // DemoViewModel 作为M的角色 // FragmentDemoBinding 作为View的角色 // 不需要继承BaseFragmentxxx,没有泛型约束,想用就用 class DemoFragment: Fragment(R.layout.fragment_demo) { //委托创建ViewModel private val viewModels by activityViewModels<DemoViewModel>() //仿造 activityViewModels()方法 委托创建ViewBinding // 会在Fragment生命周期 onDestroyView的时候销毁ViewBinding private val viewBindings by viewBindings<FragmentDemoBinding>() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) //可以调用viewBindings 的方法了 viewBindings... } }
  1. 看下怎么实现的。
Fragment.viewBindings<ViewBinding>()方法的实现
复制代码
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
51
52
53
54
55
56
57
58
59
/** * 对Fragment 扩展viewBindings方法 * 懒加载创建: * 自动判断root View 已经创建了。 * 那么使用ViewBinding::bind方法 * 如果没有则使用ViewBinding::inflater方法 * * 自动销毁: * 监听生命周期onDestroyView事件, * 把ViewBinding 置为 null * 防止内存泄漏 */ @MainThread inline fun <reified T : ViewBinding> Fragment.viewBindings( crossinline viewBindingFactory: (View?) -> ViewBindingFactory<T> = { //这做了下判断,如果当前Fragment已经有rootView了,那么就通过ViewBinding::bind的方法获取ViewBinding,反之则通过inflater方法实现 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 { //监听Fragment onDestroyView 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 } // 操作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.") } return viewBindingFactory(thisRef.view).getViewBindings().also { viewBinding -> if (viewBinding is ViewDataBinding) { viewBinding.lifecycleOwner = viewLifecycleOwner } this.binding = viewBinding } } }
ViewBindingFactory<ViewBinding> 是个什么东西
复制代码
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
interface ViewBindingFactory<T: ViewBinding> { fun getViewBindings(): T } // 通过inflate反射方法获取ViewBinding @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 } } // 通过bind反射方法获取ViewBinding @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 } }
  1. 逻辑的话,第一通过委派机制创建对象,之后再监听Fragment的生命周期的变化,把对象设置为null。如果要实现Activity这样的功能,代码类似。

最后

以上就是繁荣钻石最近收集整理的关于Kotlin 委派(ReadOnlyProperty) 仿造viewModels 写一个viewBindings通过委派机制和Kotlin的函数扩展,仿造viewModels 写一个viewBindings功能,辅助创建ViewBinding,同时在onDestroyView的回收ViewBinding的全部内容,更多相关Kotlin内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(74)

评论列表共有 0 条评论

立即
投稿
返回
顶部