MVVM学习之DataBinding

944 阅读2分钟

1. 什么是DataBinding

DataBinding是可以将我们的数据和view绑定。或者说DataBinding可以将数据和xml绑定,且还支持双向绑定:意思你改了bean里的数据,他会自动改变view里显示的数据。你改了xml里的数据,如EditText里的数据,他会自动改变bean里的数据。

动画演示(双向绑定)

DataBinding

2. DataBinding基本代码示例

通常情况下我们的xml文件的这样的

base xml

但是在databinding下的xml需要修改成如下所示

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="textStr"
            type="String" />
    </data>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center">

        <TextView
            android:id="@+id/txt"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:onClick="@{onClickListener}"
            android:text="@{textStr,default=txt}"
            android:textSize="20sp" />
    </RelativeLayout>
</layout>

可以很明显的看出变化,最外层包裹的不再是xxxLayout而是layout数据层的绑定使用`

Activity里会自动生成相应的DataBinding类,一般格式为xml名称+Binding

例如 activity_main.xml,则引用这个xml的Activity的DataBinding类名称为ActivityMainBinding

class MainActivity : AppCompatActivity(), View.OnClickListener {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        binding.textStr = "set data"
        binding.onClickListener = this
        binding.onClickUtil = OnClickUtil()
    }

    override fun onClick(v: View?) {
        binding.txt.text = "click for change data"

        val intent = Intent(this,DataBindActivity::class.java)
        startActivity(intent)
    }
}

数据设置和绑定

BaseObservable

  • bean对象需要继承 BaseObservable
  • @Bindable 标注用来表示哪个字段需要单向绑定。public修饰的可以直接用@Bindable绑定。private修饰的需要在get()方法上用@Bindable标注
  • notifyChange();刷新所有字段,notifyPropertyChanged (BR.name);刷新单个字段。注意这里说的刷新全是被@Bindable绑定的。
  • 如果BR.name出不来。建议build下项目。如果实在还是报错,报红色,不用理会一样可以启动成功。

databind show2

ObservableField

ObservableField就是对BaseObservable的简化,不用继承,不用主动调刷新代码。

class User {
    // 这里必须是常量,ObservableField<参数类型>
    // 其实写上了下面一句,就是BaseObservable,set,get, @Bindable,刷新都封装了。直接看构造方法
    val userid: ObservableField<String> = ObservableField()
    val username: ObservableField<String> = ObservableField()

    constructor(userid: String, username: String) {
        this.userid.set(userid)
        this.username.set(username)
    }
}

演示在开始的第一个动图

双向数据绑定

意思就是你改变bean对象里的值,他会主动改变xml的显示,改变xml的里的值,他会把bean对象里的属性改变了。

bean对象绑定xml显示:单向绑定@{属性值}双向绑定则是@={属性值}

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="uu"
            type="com.nzl.mvvmdemo.bean.User" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{uu.username}"
            android:textSize="16sp" />

        <EditText
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_marginTop="20dp"
            android:text="@={uu.username}" />

        <Button
            android:id="@+id/btn_search"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="60dp"
            android:text="动态查询属性" />
    </LinearLayout>
</layout>

GITHUB

项目代码MvvmDemo