相关代码
相关资料
mvp
mvvm
View: 对应于Activity和XML,负责View的绘制以及与用户交互。
Model: 实体模型。
ViewModel: 负责完成View与Model间的交互,负责业务逻辑。
当然这里只是简单说明下,具体代码建议参考google的mvvm-databinding
以前也使用过databinding但是当时发现使用过程中还是有一些比较棘手的问题,例如出现问题很难排查原因,只支持单向绑定,就没有继续使用下去,当时只是简单的写了一个Demo,
截至目前,databinding和mvvm在android中也日渐成熟,越来越多的应用采用了databinding,mvvm,rxjava,kotlin…等等具有优势的框架或者应用框架
个人对mvvm的一些理解
为什么在mvc->mvp的情况下,现在又出现了mvvm?
mvc以及mvp的对比这里就不再赘述,简单说下mvp的缺点
不适合小项目,这里的小项目指的是就几个页面的,没有复杂逻辑的项目,如果采用mvp只会增加一大堆接口,给后来者会带来一定的阅读难度
随着业务逻辑的递增,如果项目不做减法,presenter只会越来越复杂,这个时候因为presenter持有view的引用,改动起来很麻烦
需要考虑组件的生命周期,presenter越来越臃肿那么mvp想解决的问题就在presenter中又出现了
mvvm 相比 mvp 有什么优点?
平时开发中需要更新UI时,需要先获取UI控件的引用,然后再更新UI,在MVVM中,数据变化后会自动更新UI,UI的改变也能自动反馈到数据层,数据成为主导因素。
这样VM层在业务逻辑处理中只要关心数据,不需要直接和UI打交道
低耦合,数据和业务逻辑在ViewModel中,ViewModel只需要关注数据和业务逻辑,不需要和控件打交道。
控件想怎么处理数据都由控件决定,ViewModel不持有控件的引用,即便是控件层变了,ViewModel也几乎不需要更改任何代码
在MVVM中,数据发生变化后,可以直接在线程安全的情况下修改ViewModel的数据,不需要考虑要切到主线程更新UI
ViewModel带来的低耦合非常适用于团队合作
databingding
databinding是google推出的一款扩展xml的框架,直接在gradle中声明即可
android {
dataBinding {
enabled = true
}
...
}
举个简单的例子:
xmlns:app="http://schemas.android.com/apk/res-auto">
name="layoutManager"
type="android.support.v7.widget.RecyclerView.LayoutManager" />
android:id="@+id/codekk_recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="@{layoutManager}" />
然后重新build一下项目,工具会自动生成相对应的类文件,命名默认为布局文件名 + Binding ,驼峰式命名
例如布局名是activity_main,则生成的默认文件名为ActivityMainBinding
如上面示例,如果为recyclerView设置LayoutManager在代码中直接binding.layoutManager = LinearLayoutManager(this)即可
但是在使用中还是发现了一个问题,在item中设置View属性时,还是碰到了延迟的问题,
在item_codekk_op_list布局中导入了几个类和一个实体类,
在layout中设置autoLink,碰到了AppCompatTextView第一页的链接并没有变成web链接
滑动复用之后才会变化,但是在addData之后延迟2秒再刷新一下页面,效果就会起效,所以暂时没有找到其他解决办法,这种属性只能在代码中设置
结合使用
数据可以使用LiveData驱动,ViewModel继承android.arch.lifecycle下的ViewModel即可,这里提一下google在里面也实现了一个默认的AndroidViewModel
public class AndroidViewModel extends ViewModel {
@SuppressLint("StaticFieldLeak")
private Application mApplication;
public AndroidViewModel(@NonNull Application application) {
mApplication = application;
}
/**
* Return the application.
*/
@SuppressWarnings("TypeParameterUnusedInFormals")
@NonNull
public T getApplication() {
//noinspection unchecked
return (T) mApplication;
}
}
这个可以获取一个Application对象,个人暂时觉得没有多大用…,如果需要在ViewModel中获取Application对象则可以用这个,
不过推荐使用时自己实现一个ViewModel,然后结合项目的实际应用实现不同的ViewModel
abstract class NetWorkViewModel : ViewModel(), RxNetWorkListener {
val viewModelData: MediatorLiveData> = MediatorLiveData()
override fun onNetWorkError(e: Throwable) {
}
override fun onNetWorkComplete() {
}
}
在activity或者fragment则获取ViewModel对象,然后去获取数据或者实现其他功能
ViewModelProviders.of(this).get(UserViewModel.class)
按照googlesample中的写法则是使用ViewModel获取LiveData然后注册一个observe,这样在ViewModel中则直接使用liveData.setValue()或者liveData.postValue()即可.
其中的postValue适用于子线程中操作数据
如果这里使用ObservableArrayList则数据更方便,具体操作可以参考Kotlin-Sample-App
总结
总的来讲,开发确实越来越方便,不像以前需要考虑到各个方面,这里直接使用即可
但是吐槽一句题外话,使用kotlin的时候电脑卡的要死,java项目则没有这个问题…