一. 什麼是單向綁定?
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<String,Object>"/>
</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<String>"/>
<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. 效果