目录
在了解DataBinding相关注解前,可以看下这一篇文章“注解介绍”,了解一下什么是注解及注解怎么用。
@InverseMethod
此注解用于方法上,作用为转换数据。用法如下:
新建一个Binding.kt文件,并写如以下代码:
@InverseMethod("intToString")
fun stringToInt(value:String):Int{
return try {
Integer.parseInt(value)
}catch (e:Exception){
-1
}
}
fun intToString(value:Int):String{
return value.toString()
}
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="com.example.jetpacklearn.BindingKt"/>
<variable
name="clickNum"
type="androidx.databinding.ObservableInt" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.jetpacklearn.view.MyTextView
android:layout_width="50dp"
android:layout_height="50dp"
android:id="@+id/myTextView"
android:text="@{BindingKt.intToString(clickNum)}"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
注:BindingKt为编译器根据Binding.kt自动生成的Java类。
此@InverseMethod注解标记在方法上,表示此方法是一个转化方法,且需要指出对应的反转化方法。转化方法可以有多个参数,但是最后一个参数的类型必须为反转化方法的返回值类型。比如,stringToInt方法中最后一个参数的类型为Int,其与intToString方法的返回值类型相同。
@BindingAdapter
此注解标记在方法上,用来告诉数据绑定系统如何给View中的属性赋值,即告诉系统为View属性赋值的方法。以下面代码为例:
@BindingAdapter({"android:onClick", "android:clickable",requireAll = false})
public static void setOnClick(View view, View.OnClickListener clickListener,
boolean clickable) {
view.setOnClickListener(clickListener);
view.setClickable(clickable);
}
此注解表示此方法可以给view设置监听器,并且可以设置View的clickable。当注解中包含View的多个属性时,requireAll = false表示这些属性值不必同时给出(为true要同时给出)。比如,在xml文件中可以只为clickable属性赋值:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="clickable"
type="androidx.databinding.ObservableBoolean" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="@{clickable}"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
@InverseBindingAdapter
此注解标记于方法上,告诉数据绑定系统如何读取View中的属性值,同时此注解有一个参数event,其默认值为属性名+AttrChanged,用来告诉系统当目标属性值变化时,可以调用此方法来获取属性值。以下面代码为例:
@InverseBindingAdapter(attribute = "android:text", event = "android:textAttrChanged")
public static String getTextString(TextView view) {
return view.getText().toString();
}
此注解告诉数据绑定系统,当TextView的text属性变化时,可以调用此方法来获取TextView的text。
@BindingMethod
此注解的作用与@BindingAdapter注解的作用相同,都是告诉数据绑定系统如何读取View中的属性值。用法如下:
//告知数据绑定系统如何写clickTime属性
@BindingMethods(value = [BindingMethod(type = MyTextView::class, attribute = "clickTime",method = "setClickTime") ])
class MyViewBindingAdapter {
}
@BindingMethod需要作为@BindingMethods注解的参数。@BindingMethods用于标注class,这个class可以没有内容。以上代码表示,数据绑定系统可以调用setClickTime方法来设置MyTextView中clickTime属性的值。此代码为上一篇博客中Demo3的一部分。
@InverseBindingMethod
此注解与@InverseBindingAdapter注解的作用相同,用来告诉数据绑定系统,当View中的属性值变化时,如何读取属性值。用法如下:
@InverseBindingMethods( value = [ InverseBindingMethod(type = MyTextView::class,attribute = "clickTime") ] )
class MyViewBindingAdapter {
}
此注解中包含参数有:
type | 必选;标识是哪个View |
attribute | 必选;标识View中的属性 |
event | 可选;默认值为属性名+AttrChanged |
method | 可选;标识通过哪个方法读取View的属性值,默认值为get+属性名 |
通常,为了双向绑定,@InverseBindingMethod或@InverseBindingAdapter注解都会与以下格式的代码配合使用:
//通过此注解来为属性添加一个监听器listener,监听属性的变化,此listener是编译器自动生成的。
//总的来说,最终还是要通过一些onClick、onTouch、TextWatcher等监听方法来监听自定义属性的变化。
@BindingAdapter("app:clickTimeAttrChanged")
fun setClickTimeAttrChanged(myTextView: MyTextView, listener: InverseBindingListener){
//监听属性clickTime的变化
myTextView.setOnClickListener {
var clickTime = myTextView.getClickTime() + 1
myTextView.setClickTime(clickTime)
//使用listener发送属性变化通知
listener.onChange()
}
}
上述代码皆为上一篇博客中Demo3的一部分。
@Bindable
此注解用在Observable类中,可以注解字段,也可以注解get方法。编译器会根据此注解生成一个与字段对应的BR值。用法如下:
class PersionViewModel : BaseObservable(){
var persion = Persion("Jack",19)
@Bindable
fun getPersionName():String{
return persion.name
}
fun setPersionName(name:String){
if(name!=persion.name){
persion.name = name
notifyPropertyChanged(BR.persionName)
}
}
@Bindable
fun getPersionAge():Int{
return persion.age
}
fun setPersionAge(age:Int){
if(age!=persion.age){
persion.age = age
notifyPropertyChanged(BR.persionAge)
}
}
}
相关播客: