You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
classObservableViewModelextendsViewModelimplementsObservable {
privatePropertyChangeRegistrycallbacks = newPropertyChangeRegistry();
@OverridepublicvoidaddOnPropertyChangedCallback(
Observable.OnPropertyChangedCallbackcallback) {
callbacks.add(callback);
}
@OverridepublicvoidremoveOnPropertyChangedCallback(
Observable.OnPropertyChangedCallbackcallback) {
callbacks.remove(callback);
}
/** * Notifies observers that all properties of this instance have changed. */voidnotifyChange() {
callbacks.notifyCallbacks(this, 0, null);
}
/** * Notifies observers that a specific property has changed. The getter for the * property that changes should be marked with the @Bindable annotation to * generate a field in the BR class to be used as the fieldId parameter. * * @param fieldId The generated BR id for the Bindable field. */voidnotifyPropertyChanged(intfieldId) {
callbacks.notifyCallbacks(this, fieldId, null);
}
}
classObservableViewModelextendsAndroidViewModelimplementsObservable {
privatePropertyChangeRegistrycallbacks = newPropertyChangeRegistry();
publicObservableViewModel(@NonNullApplicationapplication) {
super(application);
}
@OverridepublicvoidaddOnPropertyChangedCallback(
Observable.OnPropertyChangedCallbackcallback) {
callbacks.add(callback);
}
@OverridepublicvoidremoveOnPropertyChangedCallback(
Observable.OnPropertyChangedCallbackcallback) {
callbacks.remove(callback);
}
/** * Notifies observers that all properties of this instance have changed. */voidnotifyChange() {
callbacks.notifyCallbacks(this, 0, null);
}
/** * Notifies observers that a specific property has changed. The getter for the * property that changes should be marked with the @Bindable annotation to * generate a field in the BR class to be used as the fieldId parameter. * * @param fieldId The generated BR id for the Bindable field. */voidnotifyPropertyChanged(intfieldId) {
callbacks.notifyCallbacks(this, fieldId, null);
}
}
上一章讲到了DataBinding,还是非常有感觉。光有DataBinding,没有ViewModel这个黄金搭档,MVVM是不完整的。
ViewModel
不同于windows桌面的WPF程序,Android有专门的ViewModel组件就是androidx.lifecycle:lifecycle-viewmodel
主要有以下特性
与获取ViewModel的对象(对象继承LifecycleOwner),可以是FragmentActivity或者Fragment。ViewModel和请求获取对象讲一直驻留内存直到FragmentActivity或者Fragment都完成了Finish,注意锁屏/翻转/home键,ViewModel将一直常陪伴。
ViewModel使用原则,类中代码不可拥有Activity或者Fragment的引用,也不可以有任何UI层的引用View(Button,TextView等),ViewModel必须保持高度的纯粹
ViewModel与可观察对象的合体
ViewModel对象本身只解决了生命周期同步,并不能完成绑定后,UI界面更新通知的工作
所以必须实现Observable 接口,这里由于JAVA和C#一样是单继承,所以BaseObservable不能用。选择继承ViewModel和Observable
注意,这里不能照抄官挡的代码,两个override方法应该改成public
这里MVVM架构改造的必要知识已经准备差不多了。开始正式动手
PhotoHunter Demo实战
在build.gradle里增加依赖
implementation "androidx.lifecycle:lifecycle-viewmodel:2.3.0"
创建HomeViewModel继承ObservableViewModel。
在实际使用过程中,由于ViewModel还需要应用到Application的Context,所以最后ObservableViewModel继承了AndroidViewModel。为了能获取Resource和getExternalCacheDir
照片说明,图片,下载逻辑全部移植到ViewModel来
惊喜下,完全不用管跨线程更新UI的问题
layout端改造部分
Bitmap不能直接绑定,这里用到了适配器,StackOverflow上的回答还需要改一点点,属性前缀已经被取消了,如“aaa:imageBitmap”已经不能用了
layout里面的id其实可以去掉了
最后就是MainActivity.java了
代码量少的惊人
另外手痒改了一个图标
总结部分
Android拥有比较好的MVVM的培育的土壤。初步再理解回顾下Android的MVVM
View层
其实就是layout,以及layout生成的{layout}Bind(非常非常雷同XXX.xaml.cs)负责UI呈现
ViewModel层
负责数据组织,及界面上的逻辑交互
UI Controls层
Activity或者Fragment。官网博客上说UI控制层,我个人理解更加像一个装配员,负责View和ViewModel的装配,但是本身代码逻辑已经大部移交给View和ViewModel层
图标
参考链接
ViewModel
官档
viewmodel
Bind layout views to Architecture Components
ViewModels : A Simple Example
ImageView适配器
Databinding an in-memory Bitmap to an ImageView
The text was updated successfully, but these errors were encountered: