Android DataBinding的使用(二)單向綁定

一. 什麼是單向綁定?

DataBinding的本身是對View層狀態的一種觀察者模式的實現,通過讓View與ViewModel層可觀察的對象進行綁定,當ViewModel層數據發生變化,View層也會自動進行UI的更新。 在這裏插入圖片描述

二. 單項綁定是用來幹嘛的?

前面我們講了DataBinding的作用就是實現數據綁定,但我們上面寫的代碼綁定的控件的內容,沒有隨着綁定變量的值發生改變的時候,因此每次都得重新向ViewDataBinding傳值然後跟新UI,那我們能不能讓DataBinding自己自動去刷新UI?其實單向綁定就可以實現這個效果!!

使用單向綁定刷新UI有三種

  • 使用 BaseObservable (比較麻煩)
  • 使用 ObservableField
  • 使用 ObservableCollection

三. 使用BaseObservable實現單向綁定

1. BaseObservable方法介紹

     notifyChange(); 會刷新所有UI。
     notifyPropertyChanged();  只會刷新屬於它的UI,需要綁定屬性。

2. Bean類寫法

package com.qy.databinddemo;

public class UserBean {

    @Bindable//這裏要進行綁定,否則會編譯報錯
    private String name;
    private String csdnAddress;


    public UserBean(String name, String csdnAddress) {
        this.name = name;
        this.csdnAddress = csdnAddress;
    }

    public void setName(String name) {
        this.name = name;
        //這個方法只會刷新屬於它的UI
        notifyPropertyChanged(BR.name);
    }


    public void setName2(String name) {
        this.name = name;
    }


    public void setCsdnAddress(String csdnAddress) {
        this.csdnAddress = csdnAddress;
        //這個方法會刷新所有UI
        notifyChange();
    }


    public String getName() {
        return name;
    }


    public String getCsdnAddress() {
        return csdnAddress;
    }

    @Override

    public String toString() {

        return "UserBean{" +

                "name='" + name + '\'' +

                ",csdnAddress='" + csdnAddress + '}';

    }

}

3. MainActivity中的寫法

public class MainActivity extends AppCompatActivity{

    private ActivityMainBinding binding;
    private UserBean user;
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        
        binding = DataBindingUtil
        .setContentView(this,R.layout.activity_main);
        
        user = new UserBean
        ("蘇青巖","https://blog.csdn.net/qq_35953420");
        
        //綁定數據
        binding.setData(user);
        //綁定事件
        binding.setListener(new ButtonListener());
    }

    public class ButtonListener{

        public void changeName(){
            user.setName("改變的名字");
            
            Toast.makeText(MainActivity.this,
            "改變Name",Toast.LENGTH_SHORT).show();
        }

        public void changeAddress(){
            user.setName2("百度");
            user.setCsdnAddress("www.baidu.com");
            
            Toast.makeText(MainActivity.this,
            "改變所有UI",Toast.LENGTH_SHORT).show();
        }
    }
}

4. 佈局寫法

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

 <data>
    <import 
       type="com.qy.databinddemo.UserBean"/>
       <variable
            name="data"
            type="UserBean"/>

     <!--事件監聽-->
     <import
       type="com.qy.databinddemo.MainActivity.ButtonListener"/>

      <variable
            name="listener"
            type="ButtonListener"/>

</data>

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

        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:gravity="center"
            android:text="@{data.name,default=默認值}"/>

        <TextView
            android:id="@+id/textView2"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:gravity="center"
            android:text="@{data.csdnAddress}"/>

        <!--事件監聽控件-->
        <Button
            android:id="@+id/buttonName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="修改名字"
            android:onClick="@{()->listener.changeName()}"/>

        <Button
            android:id="@+id/buttonAddress"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="修改地址"
            android:onClick="@{()->listener.changeAge()}"/>

    </LinearLayout>
</layout>

四. 使用ObservableField實現單向綁定

1. Bean類寫法

public class UserBean extends BaseObservable{
    public final ObservableField<String> name;
    public final ObservableField<String> address;

    public UserBean(ObservableField<String> name,
                    ObservableField<String> address){
        this.name=name;
        this.address=address;
    }

    public ObservableField<String> getName(){
        return name;
    }

    public ObservableField<String> getAddress(){
        return address;
    }
}

2. MainActivity中的寫法

public class MainActivity extends AppCompatActivity{

    private ActivityMainBinding binding;
    private UserBean user;
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView
        (this,R.layout.activity_main);

        user = new UserBean
        (new ObservableField<String>("蘇青巖"),
                new ObservableField<String>("CSDN蘇青巖"));
                
        //綁定數據
        binding.setData(user);
        //綁定事件
        binding.setListener(new ButtonListener());
    }

    public class ButtonListener{

        public void changeName(){
            user.setName("改變的名字");
            Toast.makeText(MainActivity.this,
                     "改變Name",Toast.LENGTH_SHORT).show();
        }

        public void changeAddress(){
            user.setName2("百度");
            user.setCsdnAddress("www.baidu.com");
            Toast.makeText(MainActivity.this,
                     "改變所有UI",Toast.LENGTH_SHORT).show();
        }
    }
}

五. 使用 ObservableCollection實現單向綁定(ObservableMap)

1. 佈局寫法(ObservableMap)

<?xmlversion="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.ObservableMap"/>
        <variable
            name="user"
            type="ObservableMap&lt;String,Object&gt;"/>
    </data>

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

        <TextView
            android:id="@+id/user1"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text='@{user["one"]}'/>
        <TextView
            android:id="@+id/user2"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text='@{user["two"]}'/>
        <TextView
            android:id="@+id/user3"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text='@{user["three"]}'/>
        <TextView
            android:id="@+id/user4"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text='@{user["four"]}'/>
    </LinearLayout>
</layout>

2. MainActivity中的寫法(ObservableMap)

public class MainActivity extends AppCompatActivity{

    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView
        (this,R.layout.activity_main);

        ObservableMap<String,Object> user = 
                                    new ObservableArrayMap< >();
        user.put("one","蘇青巖是帥哥1");
        user.put("two","蘇青巖是帥哥2");
        user.put("three","蘇青巖是帥哥3");
        user.put("four","重要的事情說三遍");
        binding.setUser(user);

    }
}

3. 效果
​​​​
在這裏插入圖片描述

六. 使用 ObservableCollection實現單向綁定(ObservableList)

1. 佈局寫法(ObservableList)

<?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"/>
        <variable
            name="user"
            type="ObservableList&lt;String&gt;"/>

   <import 
    type="com.qy.databindingdemo.MainActivity.ChangeTextView"/>
        <variable
            name="changetext"
            type="ChangeTextView"/>
</data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView
            android:id="@+id/user1"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text='@{user[0]}'/>
        <TextView
            android:id="@+id/user2"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text='@{user[1]}'/>
        <TextView
            android:id="@+id/user3"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text='@{user[2]}'/>
        <TextView
            android:id="@+id/user4"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text='@{user[3]}'/>
        <Button
            android:id="@+id/buttonOne"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{()->changetext.changeText()}"
            android:text='誰最帥??'/>
    </LinearLayout>
</layout>

2. MainActivity中的寫法(ObservableList)

public class MainActivity extends AppCompatActivity{

    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        
        binding =DataBindingUtil.setContentView
        (this,R.layout.activity_main);
        
        user = new ObservableArrayList<>();
        user.add("蘇青巖是帥哥1");
        user.add("蘇青巖是帥哥2");
        user.add("蘇青巖是帥哥3");
        user.add("重要的事情說三遍");
        binding.setUser(user);
        binding.setChangetext(new ChangeTextView());
    }

    public class ChangeTextView{
        public void changeText(){
            for(int i=0,size=user.size();i<size;i++){
                user.set(i,"蘇青巖"+i);
            }
        }
    }
}
	

3. 效果
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章