Jetpack系列:数据绑定~使用ViewModel

 

Jetpack系列:数据绑定~使用ViewModel_第1张图片

 

Hello,大家好,上一篇我们介绍了使用DataBinding库使用ObservableInt类实现简单数据绑定的功能,本篇将使用ViewModel元素,通过ViewModel来进行数据持有和用户事件的处理。

今天的Demo实现效果与入门篇效果一致,只是代码实现方式有差异:

 

Jetpack系列:数据绑定~使用ViewModel_第2张图片

 

使用ViewModel进行数据绑定,我们使用如下两种实现方式:

  1.   使用LiveData进行数据状态监听,配合使用Transformations.map将数据变更同步更新其他属性,更新UI;

  2.  定义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)}"/>    android:id="@+id/like_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"             android:onClick="@{() -> viewmodel.onLike()}"    android:text="@string/like"/>  

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绑定方式

 

使用此绑定方式,使用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);}

 

>>>>

Observable方式绑定

 

此种绑定方式,声明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);}@Bindablepublic 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来完成数据绑定吧!

 

欢迎在公众号上点击联系我们,探讨技术,互相学习,共同进步。

 

这里有更多科技咨询,新技术学习,关注我们,和我们一起成长!

 

你可能感兴趣的:(技术分享)