Jetpack架构组件_3. 数据绑定库双向绑定-1.实现方案

        模型类继承Observable

1.1实现步骤

step1.增加绑定配置

        修改app模块下的build.gradle文件,增加如下内容:

    dataBinding{
        enabled = true;
    }

step2.修改布局文件

        点根节点LinearLayout,按Alt+Enter弹出快捷菜单,点击其中Convert to data binding layout。使用双向绑定的格式是:

        @={}:双向绑定,修改控件的值后,同步修改模型属性值

<?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>
        <variable
            name="user"
            type="com.gaoting.twowaybinding.User" />
    </data>

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

        <EditText
            android:layout_margin="20dp"
            android:text="@={user.userName}"
            android:id="@+id/edtUserName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="请输入用户名!" />

        <EditText
            android:layout_margin="20dp"
            android:text="@={user.password}"
            android:id="@+id/edtPassword"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="请输入密码!" />

    </LinearLayout>
</layout>

step3.在Activity中使用

        1)创建模型对象,必须继承BaseObservable

        @Bindable:声明改属性可以用于绑定

        修改set方法,调用notifyPropertyChanged(BR.userame)发送修改通知。

package com.gaoting.twowaybinding;

import androidx.databinding.BaseObservable;
import androidx.databinding.Bindable;

public class User  extends BaseObservable {

    public User(String userName, String password) {
        this.userName = userName;
        this.password = password;
    }

    String userName;
    String password;

    @Bindable
    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
        notifyPropertyChanged(BR.userName);

    }
    @Bindable
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
        notifyPropertyChanged(BR.password);
    }
}

        2)修改Activity,使用binding对象

         ActivityMainBinding是框架自动生成的,和MainActivity对应
        使用DataBindingUtil.setContentView(this, R.layout.activity_main)获取绑定对象
        去掉setContentView(R.layout.activity_main)

        activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        user = new User("gaoting","123456");
        activityMainBinding.setUser(user);

        3)增加观察者,打印日志          

        user.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
            @Override
            public void onPropertyChanged(Observable sender, int propertyId) {
                if(propertyId == BR.userName){
                    Log.i(TAG,"我收到了userName值的变化通知,userName="+user.userName);
                }else if(propertyId == BR.password){
                    Log.i(TAG,"我收到了password值的变化通知,password="+user.password);
                }
            }
        });

         step4.调试验证方法

        1)修改布局文件(activty_main.xml )

        增加打印User和修改User按钮实现修改数据源值看UI控件有无变化,以及修改控件值看数据源有无变化。

        <Button
            android:layout_margin="20dp"
            android:id="@+id/btPrintUser"
            android:text="打印User"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

        <Button
            android:layout_margin="20dp"
            android:id="@+id/btChangeUser"
            android:text="修改User"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

         修改MainActivity.java,增加监听代码。

        activityMainBinding.btPrintUser.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i(TAG,"userName="+user.userName+",password="+user.password);
            }
        });
        activityMainBinding.btChangeUser.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               user.userName = "gaotingchange";
               user.password = "123456change";
               activityMainBinding.setUser(user);
            }
        });

         调试,可以在LogCat中查看打印日志。

1.2完整代码

         1)activity_main.xml

<?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>
        <variable
            name="user"
            type="com.gaoting.twowaybinding.User" />
    </data>

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

        <EditText
            android:layout_margin="20dp"
            android:text="@={user.userName}"
            android:id="@+id/edtUserName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="请输入用户名!" />

        <EditText
            android:layout_margin="20dp"
            android:text="@={user.password}"
            android:id="@+id/edtPassword"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="请输入密码!" />

        <Button
            android:layout_margin="20dp"
            android:id="@+id/btPrintUser"
            android:text="打印User"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

        <Button
            android:layout_margin="20dp"
            android:id="@+id/btChangeUser"
            android:text="修改User"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    </LinearLayout>
</layout>

        2)MainActivity.java

package com.gaoting.twowaybinding;

import android.os.Bundle;
import android.util.Log;
import android.view.View;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.Observable;

import com.gaoting.twowaybinding.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {
    final String TAG = "MainActivity";
    ActivityMainBinding activityMainBinding;
    User user;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        user = new User("gaoting","123456");
        activityMainBinding.setUser(user);

        user.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
            @Override
            public void onPropertyChanged(Observable sender, int propertyId) {
                if(propertyId == BR.userName){
                    Log.i(TAG,"我收到了userName值的变化通知,userName="+user.userName);
                }else if(propertyId == BR.password){
                    Log.i(TAG,"我收到了password值的变化通知,password="+user.password);
                }
            }
        });
        activityMainBinding.btPrintUser.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i(TAG,"userName="+user.userName+",password="+user.password);
            }
        });
        activityMainBinding.btChangeUser.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               user.userName = "gaotingchange";
               user.password = "123456change";
               activityMainBinding.setUser(user);
            }
        });
    }


}

         3)User.java

package com.gaoting.twowaybinding;

import androidx.databinding.BaseObservable;
import androidx.databinding.Bindable;

public class User  extends BaseObservable {

    public User(String userName, String password) {
        this.userName = userName;
        this.password = password;
    }

    String userName;
    String password;

    @Bindable
    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
        notifyPropertyChanged(BR.userName);

    }
    @Bindable
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
        notifyPropertyChanged(BR.password);
    }
}
上一篇:vue父组件如何向子组件传递数据?