序
几年前,MVVM架构设计模式出现,最具代表性的框架是数据绑定。虽然这种设计架构很新颖,但是使用起来还是有很多痛点,所以我以为这种设计架构短时间内可能不会太流行。
最近接手了一个新项目,用了MVVM,才发现MVVM只用了一两年的时间就发展的如此之快,已经成为Android开发者的必备技能之一。
主体
在数据绑定的初级阶段,最让我头疼的就是数据处理的问题。通常,为了显示数据,我必须在XML中绑定N个字段。如果是中等以上的项目,还有更痛苦的问题,比如:
你的XML可能迫切的需要if或者switch这样的判断;意想不到的空指针
2018年,谷歌推出了JetPack库,其中的ViewModel+LIveData最终将MVVM推向了一个新的高度。
视图模型
使用ViewModel取决于生命周期库:
implementation "android.arch.lifecycle:viewmodel:x.x.x"implementation "android.arch.lifecycle:extensions:x.x.x"
创建视图模型有两种主要方法:
// 获取FragmentActivity共享的ViewModelViewModelProviders.of(FragmentActivity).get(ViewModel::class.java)// 获取FragmentActivity共享的ViewModelViewModelProviders.of(Fragment).get(ViewModel::class.java)
ViewModel的共享范围主要有两个:一个是FragmentActivity,一个是Fragment。可以根据自己的需求选择分享范围。如果您想要一个应用程序级别的ViewModel(目前还不支持),您可以定制应用程序来保存ViewModel,或者使用singleton模式。
ViewModel解决的问题
1.拓展数据共享的应用场景。
一般的数据共享是活动和片段之间的数据传输。传统的方法是使用setArguments(Bundle),它有以下缺点:
可能无法预测setArguments会在Fragment的哪个周期完成,要进行异常判断;setArguments中的数据可能会发现改变,如果是Activity直接设置Fragment的数据,耦合性很高;数据较多时,Fragment会有很多的变量,影响可读性和维护性。
使用ViewModel,可以避免上述尴尬的情况,可以从ViewModel中获取任何数据:
新加数据传递,不用修改Activity的setArguments代码,Fragment也不用编写数据接收的方法;减少数据传递,不必考虑是否要删除暂时无用的代码;取数据时,请注意数据的有效性,做好判断即可;
另外,自定义视图还可以得到ViewModel,使得一些功能耦合性强的自定义视图的开发更加方便。但是需要注意的是,视图的上下文是活动类型的(不是片段),所以只能使用活动级的数据共享。
2.解决数据绑定的视图显示问题。
如果视图的显示需要大量的数据,那么XML会变得越来越臃肿,迫切需要添加一些简单的判断,比如:
如果A是空,则显示B;若B为空,则先为C;如果C是空…
虽然数据绑定支持三元运算符,可以满足if判断的需要,但在XML中维护逻辑显然比在Java或Kotlin中困难得多(没有拼写错误等。).所以我们确实需要从XML中分离出一些代码,而ViewModel非常适合这个角色。
修改前:
<?xml version="1.0" encoding="utf-8"?><layout> <data> <variable name="A" type="String" /> <variable name="B" type="String" /> <variable name="C" type="String" /> </data> <TextView android:layout_width="***tch_parent" android:layout_height="wrap_content" android:***xLines="4" android:ellipsize="middle" android:text="A != null ? A : B != null ? B : C" /> ...</layout>
修改后:
<?xml version="1.0" encoding="utf-8"?><layout> <data> <variable name="viewModel" type="ViewModel" /> </data> <TextView android:layout_width="***tch_parent" android:layout_height="wrap_content" android:***xLines="4" android:ellipsize="middle" android:text="@{viewModel.getShowContent()}" />...</layout>
LiveData
刚才我们已经讨论了ViewModel的用法,但是还有一个问题没有解决,就是数据更新的问题。解决这个问题的最好方法是观察者模式,但是如果没有处理好观察者的注册和解除绑定,就很容易出现内存溢出。LiveData可以完美解决这个问题。
我们需要添加对LiveData的依赖:
implementation "androidx.lifecycle:lifecycle-livedata:2.1.0"
这里有一个简单的例子:
// 名为openDrawer的Boolean类型的LiveDatapublic final MutableLiveData<Boolean> openDrawer = new MutableLiveData<>();// 更新openDrawer openDrawer.setValue(true)// 观察openDrawer 的值的变化openDrawer.observe(this, aBoolean -> { Toast.***keText(this, "${aBoolean}", Toast.LENGTH_SHORT).show(); });
LiveData的子类是MutableLiveData,里面有value属性保存最新的值。订阅LiveData的变化,直接调用LiveData.observe()即可:
public void Observer(@ NonNull life cycle owner owner,@ NonNull Observer & lt?超级T & gt观察者)拥有者:注册期会在拥有者被消灭时解除对观察者的绑定。观察者:改变观察值的回调函数。
所有者可以直接使用活动或片段。如果不了解使用生命周期,可以查看相关资料。
摘要
最后,我画了一个架构图来总结最新的MVVM使用架构:
Activity:处理UI问题,但是应该尽可能避免,数据绑定应该尽可能统一使用。ViewModel:保存页面需要的数据,如果功能复杂,可以拆分成多个。数据绑定:处理UI视图,并为数据显示保存ViewModel。如果页面功能复杂,可以再细分ViewModel和DataBinding。
如果你对MVVM有更深入的了解,请留言一起学习。
本文来自MR.特别人士投稿,不代表舒华文档立场,如若转载,请注明出处:https://www.chinashuhua.cn/24/613435.html