Android DataBinding使用-数据绑定

2020-05-01  本文已影响0人  超人TIGA

demo地址:https://github.com/TonyDash/DataBinding

数据绑定

实现数据变化之后自动刷新UI的方式有三种:BaseObservable、ObservableField、ObservableCollection。

-BaseObservable

-ObservableField

-ObservableCollection

ObservableField

ObservableField可以理解为官方为我们实现的BaseObservable封装类,主要是一些基本类型。例如:

ObservableBoolean
ObservableByte
ObservableChar
ObservableShort
ObservableInt
ObservableLong
ObservableFloat
ObservableDouble
ObservableParcelable

很多时候,我们直接用这些来声明即可。首先,我们建一个model层的实体类:

class Animal(){
    val nickName = ObservableField<String>()
    val age = ObservableInt()
}

然后在xml布局中绑定这个model和增加对应的点击事件:

<?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">

    <data>
        <variable
            name="animal"
            type="com.example.cjy.databinding.bean.Animal" />
        <variable
            name="clickEvent"
            type="com.example.cjy.databinding.clickevent.AnimalClickEvent" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/tvAnimalNickName"
            android:textColor="@color/black"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{animal.nickName ,default = nickName}"
            android:onClick="@{clickEvent::animalClick}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:textColor="@color/black"
            android:layout_marginTop="10dp"
            android:id="@+id/tvAnimalAge"
            android:layout_width="wrap_content"
            android:text="@{String.valueOf(animal.age) ,default=1}"
            android:layout_height="wrap_content"
            android:onClick="@{clickEvent::animalClick}"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tvAnimalNickName" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

然后在activity中绑定数据源:

class AnimalActivity:AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_animal)
        val animalBinding:ActivityAnimalBinding =
            DataBindingUtil.setContentView(this,R.layout.activity_animal)
        val dog = Animal()
        dog.nickName.set("小黄")
        dog.age.set(3)
        animalBinding.animal = dog
        animalBinding.clickEvent = AnimalClickEvent(dog)
    }
}
class AnimalClickEvent(private val animal:Animal) {
    fun animalClick(view: View) {
        when (view.id) {
            R.id.tvAnimalNickName -> {
                animal.nickName.set("大黄")

            }
            R.id.tvAnimalAge->{
                animal.age.set(8)

            }
        }
    }
}

到这里,就实现了数据的单向绑定了。

ObservableCollection

collection一般包含ObservableArrayMap、ObservableArrayList、ObservableMap这几种。
在使用的时候,其实跟ObservableField大同小异。
①首先,在布局中声明一个ObservableArrayMap,并在tvAnimalInfo中,利用animalInfo[key]来找到你想要的位置的信息。

<?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">

    <data>

        <variable
            name="animalInfo"
            type="androidx.databinding.ObservableArrayMap&lt;String,String&gt;" />

        <variable
            name="key"
            type="String" />

        <variable
            name="animal"
            type="com.example.cjy.databinding.bean.Animal" />

        <variable
            name="clickEvent"
            type="com.example.cjy.databinding.clickevent.AnimalClickEvent" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/tvAnimalNickName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{clickEvent::animalClick}"
            android:text="@{animal.nickName ,default = nickName}"
            android:textColor="@color/black"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tvAnimalAge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:onClick="@{clickEvent::animalClick}"
            android:text="@{String.valueOf(animal.age) ,default=1}"
            android:textColor="@color/black"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tvAnimalNickName" />

        <TextView
            android:id="@+id/tvAnimalInfo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:onClick="@{clickEvent::animalClick}"
            android:text="@{animalInfo[key],default = tom}"
            android:textColor="@color/black"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tvAnimalAge" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

②布局加好之后,就到对应的activity逻辑了。

class AnimalActivity:AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_animal)
        val animalBinding:ActivityAnimalBinding =
            DataBindingUtil.setContentView(this,R.layout.activity_animal)
        val dog = Animal()
        dog.nickName.set("小黄")
        dog.age.set(3)
        animalBinding.animal = dog
        val map = ObservableArrayMap<String,String>()
        map["pat"] = "dog"
        animalBinding.animalInfo = map
        animalBinding.key = "pat"
        animalBinding.clickEvent = AnimalClickEvent(dog,map)
    }
}

这里需要说明下的就是,xml中声明的key,也需要我们在activity中绑定数据的时候填入。
然后增加点击事件:

class AnimalClickEvent(private val animal:Animal,private val map:ObservableArrayMap<String,String>) {
    fun animalClick(view: View) {
        when (view.id) {
            R.id.tvAnimalNickName -> {
                animal.nickName.set("大黄")

            }
            R.id.tvAnimalAge->{
                animal.age.set(8)

            }
            R.id.tvAnimalInfo->{
                map["pat"] = "cat"
            }
        }
    }
}

到这里,就完成了集合的单向数据绑定了。

另外,需要注意的地方有:
1、表达式里面,不能有数字,如果是数字,xml会默认这是一个控件的id,到编译的时候,就会报错,说找不到这个id的资源,例如@{10},这样就会报错。
2、不能换行,也不能有中文。

上一篇下一篇

猜你喜欢

热点阅读