Hello,大家好,上一篇我们介绍了使用DataBinding库使用ObservableInt类实现简单数据绑定的功能,本篇将使用ViewModel元素,通过ViewModel来进行数据持有和用户事件的处理。
今天的Demo实现效果与入门篇效果一致,只是代码实现方式有差异:
使用ViewModel进行数据绑定,我们使用如下两种实现方式:
使用LiveData进行数据状态监听,配合使用Transformations.map将数据变更同步更新其他属性,更新UI;
定义ViewModel实现Observable接口进行数据变更通知。
首先,我们分析下两种绑定方式的共同点:
1. xml配置文件中,针对FirstName、LastName、Likes标签的显示内容,Likes Button的处理行为,都使用了ViewModel的属性:
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewmodel.firstName}"/>
android:id="@+id/lastname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewmodel.lastName}"/>
android:id="@+id/likes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{Integer.toString(viewmodel.likes)}"/>
2. 导致图片更新的逻辑都采用自定义标签的方式:
//BindingAdapters类中,通过注解的方式自定义标签
@BindingAdapter("app:popularityIcon")
public static void popularityIcon(ImageView view, Popularity popularity) {
int color = getAssociatedColor(popularity, view.getContext());
//添加图片着色
ImageViewCompat.setImageTintList(view, ColorStateList.valueOf(color));
//添加图片Resource对象
view.setImageDrawable(getDrawablePopularity(popularity, view.getContext()));
}
//xml声明,引用app:popularityIcon标签
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:popularityIcon="@{viewmodel.popularity}"/>
注意:使用自定义标签可以方便在XML中配置UI的显示方法,但是一定记得在使用前先在代码中通过注解定义,否则编译会出错!
两种数据绑定模式,在likes数量发生变化时,都可以通知图片进行更新,从布局上来看,都是更改了ViewModel.popularity值,接下来介绍下两种更新方式的不同。
>>>>
使用此绑定方式,使用LiveData类型的likes变量,在点击Button时,触发其发生变化,映射popularity变量进行修改,从而通知UI更新:
LiveData
popularity = Transformations.map(likes, new Function () { @Override
public Popularity apply(Integer input) {
if (input > 9) {
return Popularity.STAR;
} else if (input > 4) {
return Popularity.POPULAR;
} else {
return Popularity.NORMAL;
}
}
});
public void onLike() {
likesNum.setValue(likesNum.getValue() > -1 ? likesNum.getValue() : 0);
}
>>>>
此种绑定方式,声明likes变量类型为ObservableInt,在点击Button更新likes值时,通知popularity属性更新,从而刷新UI显示。
private ObservableInt likes = new ObservableInt(0);
public void onLike() {
likes.set(likes.get() + 1);
// You control when the @Bindable properties are updated using `notifyPropertyChanged()`.
notifyPropertyChanged(com.stone.databinding.BR.popularity);
}
@Bindable
public Popularity getPopularity() {
int likesNum = likes.get();
if (likesNum > 9) {
return Popularity.STAR;
} else if (likesNum > 4) {
return Popularity.POPULAR;
} else {
return Popularity.NORMAL;
}
}
注意:使用这种绑定方式,通知更新的fieldId对应的Get方法需要增加@Bindable注解,才可被库识别进行映射。
源码在此:https://gitee.com/danvie/danvie-databinding
Google建议使用LiveData方式进行绑定,因为它是针对生命周期感知的,使用此种方式可以带来如下几点好处:
确保UI显示与数据同步
不存在内存泄漏
活动停止时不存在Crash
不需要手动维护生命周期中数据处理逻辑
始终保持最新数据显示
适当的配置更改
共享资源
你的App有没有遇到此类数据绑定的场景呢?尝试用DataBinding来完成数据绑定吧!
欢迎在公众号上点击联系我们,探讨技术,互相学习,共同进步。
这里有更多科技咨询,新技术学习,关注我们,和我们一起成长!