Databinding使用篇三

2021-01-03  本文已影响0人  Method

不可观察的数据对象

数据改变了,界面没有更新最新的数据

xml布局

<data>
    <variable
        name="people"
        type="com.example.hellojetpack.databinding.PeopleBean" />
</data>
<TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{people.name +`:`+String.valueOf(people.age)}"
/>

数据对象

class PeopleBean {
    var name:String = ""
    var age:Int = 0
}

Activity

val people = PeopleBean()
    lateinit var binding: ActivityObservableBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_observable)
        people.apply {
            name = "sunhao"
            age = 29
        }
        binding = DataBindingUtil.setContentView<ActivityObservableBinding>(
            this,
            R.layout.activity_observable
        )
        binding.people = people
    }

    /**
     * 观察特定的变量
     */
    fun modifyVar(view: View) {
        people.apply {
            name = "chenmm"
            age = 26
        }
        println("${people.name} : ${people.age}")
    }

打印结果

I/System.out: chenmm : 26

数据变了并没有驱动UI进行更新,怎么解决数据更新可以带动UI更新?
采用可观察的数据对象

可观察的数据对象

可观察性是指一个对象将其数据变化告知其他对象的能力。通过数据绑定库,您可以让对象、字段或集合变为可观察。

当其中一个可观察数据对象绑定到界面并且该数据对象的属性发生更改时,界面会自动更新。

可观察字段

在创建实现 Observable 接口的类时要完成一些操作,但如果您的类只有少数几个属性,这样操作的意义不大。在这种情况下,您可以使用通用 Observable 类和以下特定于基元的类,将字段设为可观察字段:

class PeopleBean {
    val name = ObservableField<String>()
    val age = ObservableInt()
}
fun modifyVar(view: View) {
   people.apply {
           name.set("chenmm")
           age.set(26)
       }
       println("${people.name.get()} : ${people.age.get()}")
}

结果 UI数据更新

可观察集合

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

<?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>
        <import type="android.databinding.ObservableList"/>
        <import type="android.databinding.ObservableMap"/>
        <variable
            name="list"
            type="ObservableList&lt;String&gt;"/>
        <variable
            name="map"
            type="ObservableMap&lt;String,String&gt;"/>
        <variable
            name="index"
            type="int"/>
        <variable
            name="key"
            type="String"/>
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.leavesc.databinding_demo.Main12Activity">

        <TextView
            ···
            android:padding="20dp"
            android:text="@{list[index],default=xx}"/>

        <TextView
            ···
            android:layout_marginTop="20dp"
            android:padding="20dp"
            android:text="@{map[key],default=yy}"/>

        <Button
            ···
            android:onClick="onClick"
            android:text="改变数据"/>

    </LinearLayout>
</layout>
    private ObservableMap<String, String> map;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMain12Binding activityMain12Binding = DataBindingUtil.setContentView(this, R.layout.activity_main12);
        map = new ObservableArrayMap<>();
        map.put("name", "leavesC");
        map.put("age", "24");
        activityMain12Binding.setMap(map);
        ObservableList<String> list = new ObservableArrayList<>();
        list.add("Ye");
        list.add("leavesC");
        activityMain12Binding.setList(list);
        activityMain12Binding.setIndex(0);
        activityMain12Binding.setKey("name");
    }

    public void onClick(View view) {
        map.put("name", "leavesC,hi" + new Random().nextInt(100));
    }
image

可观察整个对象

实现 Observable 接口的类允许注册监听器,以便它们接收有关可观察对象的属性更改的通知。

Observable 接口具有添加和移除监听器的机制,但何时发送通知必须由您决定。为便于开发,数据绑定库提供了用于实现监听器注册机制的 BaseObservable 类。

  1. 实现 BaseObservable 的数据类负责在属性更改时发出通知。
  2. 具体操作过程是向 getter 分配 Bindable 注释,然后在 setter 中调用 notifyPropertyChanged() 方法
class User : BaseObservable() {
        
        @get:Bindable
        var firstName: String = ""
            set(value) {
                field = value
                //注意参数
                notifyPropertyChanged(BR.firstName)
            }

        @get:Bindable
        var lastName: String = ""
            set(value) {
                field = value
                notifyPropertyChanged(BR.lastName)
            }
    }

notifychange() 更新全部字段

var finalPrice:Float = 0.0f
         @Bindable
         get() {
            return field
         }
         set(value) {
             field = value
             notifyPropertyChanged(BR.finalPrice)
         }

    var offPrice:Float = 0f
        @Bindable
        get() = field
        set(value) {
            field = value
            //更新其他所有字段(不包括 添加Bindable的字段)
            notifyChange()
        }
    var buyCount:Long = 0

双向绑定

双向绑定的意思即为当数据改变时同时使视图刷新,而视图改变时也可以同时改变数据

看以下例子,当 EditText 的输入内容改变时,会同时同步到变量 goods,绑定变量的方式比单向绑定多了一个等号:android:text="@={goods.name}"

<?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>
        <import type="com.leavesc.databinding_demo.model.ObservableGoods"/>
        <variable
            name="goods"
            type="ObservableGoods" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".Main10Activity">

        <TextView
            ···
            android:text="@{goods.name}" />

        <EditText
            ···
            android:text="@={goods.name}" />

    </LinearLayout>
</layout>
public class Main10Activity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMain10Binding activityMain10Binding = DataBindingUtil.setContentView(this, R.layout.activity_main10);
        ObservableGoods goods = new ObservableGoods("code", "hi", 23);
        activityMain10Binding.setGoods(goods);
    }

}
image
上一篇 下一篇

猜你喜欢

热点阅读