Android中的MVP筆記之四: Data Binding 庫的使用之數據綁定是不是雙向的

數據綁定是不是雙向?java

舉一個具體的TextView例子說明android

<TextView
    android:id="@+id/tv_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:text="@{brCompany.nameField}"
    android:textSize="16sp" />

上面的一句 android:text="@{brCompany.nameField}" git

能夠達到((TextView)findViewById(R.id.tv_name)).setText(brCompany.nameField.get())效果,也就是對象數據自動綁定到了控件上。app

反之假如調用了TextView控件的setText("test");方法brCompany.nameField成員變的值是否會相應的變化,也就是控件屬性數據變化後,是否會引發綁定的數據對象的成員變量的值的變化。ide

 

Data Binding 庫是支持數據雙向綁定的,但須要使用 "@={brCompany.nameField}"而不是 "@{brCompany.nameField}"佈局

 

layout佈局以下this

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable
            name="brCompany"
            type="com.example.databindtest.BRCompany" />
        <variable
            name="actionHandler"
            type="com.example.databindtest.ActionHandler" />

        <import type="android.graphics.drawable.Drawable" />
        <import type="com.example.databindtest.DateUtil" />
    </data>

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/br_company_item_root_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/cardview_dark_background"
        android:padding="8dp">

        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="8dp">

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <android.support.v7.widget.CardView
                    android:id="@+id/cv_wrap"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="8dp">
                    <ImageView
                        android:id="@+id/iv_icon"
                        android:layout_width="80dp"
                        android:layout_height="80dp"
                        android:minHeight="80dp"
                        android:minWidth="80dp"
                        android:layout_centerVertical="true"
                        android:onClick="@{(tv) -> actionHandler.showImageDialog(brCompany.getBRIcon())}"
                        app:error="@{@drawable/ic_launcher}"
                        app:imageUrl="@{brCompany.iconField}" />
                </android.support.v7.widget.CardView>

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="8dp"
                    android:layout_marginTop="8dp"
                    android:layout_toRightOf="@id/cv_wrap"
                    android:orientation="vertical">

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content">

                        <TextView
                            android:id="@+id/tv_name"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_weight="1"
                            android:text="@={brCompany.nameField}"
                            android:textSize="16sp" />

                        <TextView
                            android:id="@+id/tv_create_time"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_weight="1"
                            android:text="@{DateUtil.getTime(brCompany.createTimeField)}"
                            android:textSize="16sp" />
                    </LinearLayout>

                    <TextView
                        android:id="@+id/tv_info"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:ellipsize="end"
                        android:maxLines="3"
                        android:onClick="@{(tv) -> actionHandler.showTextDialog(brCompany.toString())}"
                        android:text="@={brCompany.infoField}" />
                </LinearLayout>
            </RelativeLayout>
        </android.support.v7.widget.CardView>
    </FrameLayout>
</layout>

 

java代碼以下spa

 

package com.example.databindtest;

import android.databinding.DataBindingUtil;
import android.databinding.Observable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

import com.example.databindtest.databinding.BrCompanyItemLayoutBinding;

public class InteractWithEachOtherActivity extends AppCompatActivity {

    private BRCompany mCompany;
    private BrCompanyItemLayoutBinding mBinding;
    private int mCount = 0;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.interact_with_each_other_activity_layout);
        mBinding = DataBindingUtil.bind(findViewById(R.id.br_company_item_root_layout));
        mCompany = BRCompany.getCompanyList().get(0);
        mBinding.setActionHandler(new ActionHandler(this));
        mBinding.setBrCompany(mCompany);
        initPropertyChanged();
    }

    public void updateData(View view) {
        mCount++;
        mBinding.tvInfo.setText(mCount+""+mBinding.tvInfo.getText());
        mBinding.tvName.setText(mCount+""+mBinding.tvName.getText());
    }


    private void initPropertyChanged() {
        if(mCompany == null) {
            return;
        }

        mCompany.infoField.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
            @Override
            public void onPropertyChanged(Observable observable, int i) {
                Log.d("onPropertyChanged","info:"+mCompany.infoField.get());
            }
        });

        mCompany.nameField.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
            @Override
            public void onPropertyChanged(Observable observable, int i) {
                Log.d("onPropertyChanged","name:"+mCompany.nameField.get());
            }
        });
    }

}

 

上面的updateData方法執行後,調用了 TextView的 setText 方法,假如會自動調用OnPropertyChangedCallback裏的方法,而且打印輸入的是新的值,和調用setName,setInfo,同樣的效果,就能夠證實是數據是雙向綁定的。.net

 

完整代碼請查看雙向綁定

https://git.oschina.net/null_979_4294/MVP-DataBinding1

相關文章
相關標籤/搜索