Android 练手之旅——DataBinding简介
soapgu opened this issue · comments
前言
DataBinding是一个非常非常重要的功能,它是实现MVVM架构的关键技术。
拥有了DataBinding才真正做到了UI和数据逻辑解耦。
这里跟着教程一步步学是最好的
android-databinding
中文版教程
环境准备
在模块级的build.gradle里面加入
android {
dataBinding {
enabled = true
}
}
这里有坑,
- 首先dataBinding 这个标记都不认
项目级里面的gradle版本需要升级到最新(原版3.4是不支持的)
classpath 'com.android.tools.build:gradle:4.1.2'
2.gradle工具版本也要升级到新版
gradle-wrapper.properties里面的distributionUrl
layout修改
- 到UI根元素下利用IDE改成binding模式
select Show Context Actions, then Convert to data binding layout
2.在data增加绑定值
<data>
<variable
name="viewmodel"
type="com.example.android.databinding.basicsample.data.SimpleViewModel"/>
</data>
3 在相关View元素中增加绑定表达式
<TextView
android:id="@+id/plain_name"
android:text="@{viewmodel.name}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="128dp"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/name_label" />
和WPF没有太多区别,支持.下去嵌套
4 绑定方法
<Button
android:id="@+id/like_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:onClick="@{()->viewmodel.onLike()}"
android:text="@string/like"
app:layout_constraintBottom_toTopOf="@+id/progressBar"
app:layout_constraintEnd_toEndOf="@+id/imageView"
app:layout_constraintStart_toStartOf="@+id/imageView"
app:layout_constraintTop_toBottomOf="@+id/likes" />
绑定方法还要直观易懂,感觉比WPF的绑定方法做得还要好
- 布局文件Binding类,这是我们的DataBinding组件帮我们自动完成的,虽然不需要额外的工作但是蛮重要,需要说明下
系统会为每个布局文件生成一个绑定类。默认情况下,类名称基于布局文件的名称,它会转换为 Pascal 大小写形式并在末尾添加 Binding 后缀,就是 {layoutname}Binding。
有兴趣的可以转到java(genrerate)
Activity部分绑定值传入
val binding : PlainActivityBinding =
DataBindingUtil.setContentView(this, R.layout.plain_activity)
binding.lifecycleOwner = this
binding.viewmodel = viewModel
这部分代码属于KT,语法上没有啥障碍
这里数据对象就是viewmodel ,binding.viewmodel和前面布局xml文件里面data定义的变量一致。ViewModel又是一个走上MVVM之路的重要杀器,这里暂且不表
绑定数据类型定义及更新通知
这里数据的更新通知到UI有几种方式实现
1 继承BaseObservable ,Get增加@bindable标记Set 调用notifyPropertyChanged(BR.{prop})。
看到代码学过WPF的同学心领神会。
private static class User extends BaseObservable {
private String firstName;
private String lastName;
@Bindable
public String getFirstName() {
return this.firstName;
}
@Bindable
public String getLastName() {
return this.lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
notifyPropertyChanged(BR.firstName);
}
public void setLastName(String lastName) {
this.lastName = lastName;
notifyPropertyChanged(BR.lastName);
}
}
在编译期间,Bindable 注释会在 BR 类文件中生成一个条目
2 LiveData组件
private val _name = MutableLiveData("Ada")
private val _lastName = MutableLiveData("Lovelace")
private val _likes = MutableLiveData(0)
val name: LiveData<String> = _name
val lastName: LiveData<String> = _lastName
val likes: LiveData<Int> = _likes
3 ObservableField
绑定适配器
展开篇幅很大,这里概况下。学过WPF的同学 可以理解为Attached DependencyProperty( 附加依赖属性 )
所以这里的方法是静态的
@BindingAdapter("android:paddingLeft")
public static void setPaddingLeft(View view, int oldPadding, int newPadding) {
...
}
关键点
1 BindingAdapter标记
2 标记参数,android:paddingLeft,可以在layout中声明相关(附加)属性
3 View,这里可以更具体类的对象,比如ImageView
4 target value
这里是最典型用法,还有很多扩展,也可以是事件监听器对象。满足各种需要,总有一款适合你
Convesion
简述下,学过WPF的同学可以和Converter对标
@BindingConversion
public static ColorDrawable convertColorToDrawable(int color) {
return new ColorDrawable(color);
}
大家可以体会下代码。
这里和WPF不同之处在于无需在layout的xml显示定义。作用域待考察,似乎是模块内的
总结下,Android的DataBinding非常的优雅。学过WPF的同学应该是无障碍理解。