Android DataBinding单向绑定

Android DataBinding单向绑定


一、Android DataBinding 基础使用
二、Android DataBinding单向绑定
三、Android DataBinding 双向数据绑定、事件绑定、使用类方法
四、Android DataBinding 运算符、BindingAdapter、 BindingConversion


DataBinding 是google发布的一个数据绑定框架,用于降低布局和逻辑的耦合性,使代码逻辑更加清晰。大量减少 Activity 内的代码,数据能够单向或双向绑定到 layout 文件中,有助于防止内存泄漏,而且能自动进行空检测以避免空指针异常。

实现数据变化自动驱动 UI 刷新的方式有三种:BaseObservableObservableFieldObservableCollection

BaseObservable

一个简单的ViewModel 类被更新后,并不会让 UI 自动更新。而数据绑定后,我们自然会希望数据变更后 UI 会即时刷新,Observable 就是为此而生的概念。

BaseObservable 提供了 notifyChange()notifyPropertyChanged() 两个方法。

  • notifyChange()

它会刷新所有的值。

  • notifyPropertyChanged()

它只会根据对应的BRflag更新,该 BR 的生成通过注释 @Bindable 生成,可以通过 BR notify 特定属性关联的视图。

  • 由于kotlin的属性默认是public修饰,所以可以直接在属性上@Bindable, 如何设置了修饰符且不为public的话,则可使用@get BIndable(表示在get()方法上标记@Bindable
import androidx.databinding.BaseObservable
import androidx.databinding.Bindable
import com.github.ixiaow.sample.BR

class UserInfo : BaseObservable() {
	// 对name进行@Bindable标志,然后会生成BR.name
    @Bindable
    var name: String = ""
        set(value) {
            field = value
            // 当name,发生改变时只会刷新与name相关控件的值,不会刷新其他的值
            notifyPropertyChanged(BR.name)
        }

    @get: Bindable
    var password: String = ""
        set(value) {
            field = value
            // 当password 发生改变时,也会刷新其他属性相关的控件的值
            notifyChange()
        }
}

布局文件:

<?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="userInfo" type="com.github.ixiaow.sample.model.UserInfo"/>
    </data>
    <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">

        <TextView
                app:layout_constraintVertical_chainStyle="spread"
                android:id="@+id/mUserName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{userInfo.name}"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{userInfo.password}"
                app:layout_constraintTop_toBottomOf="@id/mUserName"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
  1. OnPropertyChangedCallback

    实现了 Observable 接口的类允许注册一个监听器OnPropertyChangedCallback,当可观察对象的属性更改时就会通知这个监听器。

    当中 propertyId 就用于标识特定的字段

user.addOnPropertyChangedCallback(object : Observable.OnPropertyChangedCallback(){
     override fun onPropertyChanged(sender: Observable, propertyId: Int) {
                
     }
})

ObservableField

继承于 Observable 类相对来说限制有点高,且也需要进行notify 操作,因此为了简单起见可以选择使用 ObservableField。 可以理解为官方对 BaseObservable 中字段的注解和刷新等操作的封装,官方原生提供了对基本数据类型的封装,例如 ObservableBoolean、ObservableByte、ObservableChar、ObservableShort、ObservableInt、ObservableLong、ObservableFloat、ObservableDouble 以及 ObservableParcelable ,也可通过 ObservableField 泛型来申明其他类型。

data class ObservableUser(
    var name: ObservableField<String>,
    var password: ObservableField<String>
)

ObservableUser属性值的改变都会立即触发 UI 刷新,概念上与Observable 区别不大,具体效果可看下面提供的源代码,这里不再赘述

ObservableCollection

dataBinding 也提供了包装类用于替代原生的 ListMap,分别是 ObservableListObservableMap,当其包含的数据发生变化时,绑定的视图也会随之进行刷新

<?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="androidx.databinding.ObservableList"/>
        <import type="androidx.databinding.ObservableMap"/>
        <import type="com.github.ixiaow.sample.model.User"/>
        <variable name="index" type="int"/>
        <variable name="key" type="String"/>
        <variable name="list" type="ObservableList&lt;User>"/>
        <variable name="map" type="ObservableMap&lt;String, User>"/>
    </data>
    <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">

        <TextView
                app:layout_constraintVertical_chainStyle="spread"
                android:id="@+id/mUserName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{list[index].name}"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

        <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{map[key].password}"
                app:layout_constraintTop_toBottomOf="@id/mUserName"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val dataBinding: ActivityMainBinding =
            DataBindingUtil.setContentView(this, R.layout.activity_main)
        
        dataBinding.map = ObservableArrayMap<String, User>().apply {
            "android" to User("android", "12367")
            "java" to User("java", "12534")
            "c" to User("c", "12344")
            "c++" to User("c++", "14423")
            "c#" to User("c#", "12334")
        }

        dataBinding.key = "c"

        dataBinding.list = ObservableArrayList<User>().apply {
            add(User("android", "123"))
            add(User("java", "1234"))
            add(User("c", "1235"))
            add(User("c++", "123447"))
        }

        dataBinding.index = 3
    }
}

本地址:https://blog.csdn.net/xiaowu_zhu/article/details/91876068

发布了44 篇原创文章 · 获赞 28 · 访问量 4万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览