数据绑定是否是双向?
举一个具体的TextView例子说明
<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}"
可以达到((TextView)findViewById(R.id.tv_name)).setText(brCompany.nameField.get())效果,也就是对象数据自动绑定到了控件上。
反之假如调用了TextView控件的setText("test");方法brCompany.nameField成员变的值是否会相应的变化,也就是控件属性数据变化后,是否会引起绑定的数据对象的成员变量的值的变化。
Data Binding 库是支持数据双向绑定的,但需要使用 "@={brCompany.nameField}"而不是 "@{brCompany.nameField}"
layout布局如下
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代码如下
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,一样的效果,就可以证明是数据是双向绑定的。
完整代码请查看
https://git.oschina.net/null_979_4294/MVP-DataBinding1