配置
1.在app的build.gradle下添加:
android {
···
buildFeatures {
dataBinding true
}
···
}
基本用法
1.在布局文件的根布局 按下 alt+enter,选择databinding布局:
然后就多出了一个layout将原布局包装了起来
并多出来了一个< data >< /data > 用于绑定数据
2.这里我们先创建一个实体类 TestBean(简单粗暴):
public class TestBean {
private String str;
public TestBean(String str){
this.str=str;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
}
3.在布局文件的data标签里声明需要使用到的变量名、类的全路径
<data>
<variable
name="bean"
type="com.zdww.androidframe2020.bean.TestBean" />
</data>
或者可以先将类import进来:
<data>
<import type="com.zdww.androidframe2020.bean.TestBean"/>
<variable
name="bean"
type="TestBean" />
</data>
4.绑定数据:
<TextView
android:id="@+id/main_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30dp"
android:text="@{Bean.str,default=defaultvalue}" //这里
android:layout_margin="15dp"
android:paddingStart="15dp"
/>
5.Activity中:
ActivityMainBinding mainBinding= DataBindingUtil.setContentView(this,R.layout.activity_main);
TestBean testBean=new TestBean("str");
mainBinding.setBean(testBean);
6.也可以直接获取控件,而不用findByView
mainBinding.mainTv.setText("sss");
7.Fragment中使用:
layout:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="Bean"
type="com.zdww.androidframe2020.bean.TestBean" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Fragment.BlankFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>
</layout>
java:
FragmentBlankBinding blankBinding= DataBindingUtil.inflate(inflater, R.layout.fragment_blank,container,false);
TestBean bean=new TestBean("ss");
blankBinding.setBean(bean);
单项绑定
我们希望数据刷新后前端能够实时刷新
BaseObservable
BaseObservable 提供了 notifyChange() 和 notifyPropertyChanged() 两个方法,前者会刷新所有的值域,后者则只更新对应 BR 的 flag,该 BR 的生成通过注释 @Bindable 生成,可以通过 BR notify 特定属性关联的视图。
(只有注释了@Bindable的才可以单独刷新,其余的无法单独刷新)
示例:
layout:
<TextView
android:id="@+id/main_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30dp"
android:text="@{Bean.str,default=defaultvalue}"
android:layout_margin="15dp"
android:paddingStart="15dp"
/>
<TextView
android:id="@+id/main_tv2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30dp"
android:text="@{Bean.i,default=defaultvalue}"
android:layout_margin="15dp"
android:paddingStart="15dp"
/>
<Button
android:id="@+id/main_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="button"
android:textSize="30dp"
/>
bean(没有注释@Bindable):
public class TestBean extends BaseObservable{
private String str;
private String i;
public TestBean(String str,int i){
this.str=str;
this.i=i;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
notifyChange();
}
public String getI() {
return i;
}
public void setI(String i) {
this.i = i;
}
}
activity:
ActivityMainBinding mainBinding= DataBindingUtil.setContentView(this,R.layout.activity_main);
TestBean testBean=new TestBean("str",0);
mainBinding.mainBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
testBean.setStr("ssss");
testBean.setI(22);
}
});
两个均改变了
bean(添加了@Bindable注释):
不注释的话,notifyPropertyChanged的BR里是选不到str的(坏笑)
public class TestBean extends BaseObservable {
@Bindable
private ObservableField<String> str;
private String i;
public TestBean(String str,String i){
this.str=new ObservableField<>(str);
this.i=i;
}
public ObservableField<String> getStr() {
return str;
}
public void setStr(String str) {
this.str = new ObservableField<>(str);
// notifyChange();
notifyPropertyChanged(BR.str);
}
public String getI() {
return i;
}
public void setI(String i) {
this.i = i;
}
}
只有str改变了
ObservableField
其实同时还有:ObservableBoolean、ObservableByte、ObservableChar、ObservableShort、ObservableInt、ObservableLong、ObservableFloat、ObservableDouble 以及 ObservableParcelable 为了方便起见,我们可以使用泛型的ObservableField。
ObservableField是不需要使用notify()方法来刷新的:
示例:
bean:
public class TestBean {
private ObservableField<String> str;
public TestBean(String str){
this.str=new ObservableField<>(str);
}
public ObservableField<String> getStr() {
return str;
}
public void setStr(ObservableField<String> str) {
this.str = str;
}
}
activity:
ActivityMainBinding mainBinding= DataBindingUtil.setContentView(this,R.layout.activity_main);
TestBean testBean=new TestBean("str");
mainBinding.setBean(testBean);
mainBinding.mainBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
testBean.getStr().set("ssss");
}
});
layout:
<TextView
android:id="@+id/main_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30dp"
android:text="@{Bean.str,default=defaultvalue}"
android:layout_margin="15dp"
android:paddingStart="15dp"
android:textColor="@color/black"
/>
<Button
android:id="@+id/main_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="button"
android:textSize="30dp"
/>
双向绑定
单项绑定:
android:text="@{Bean.str,default=defaultvalue}"
双线绑定:
多了个 “ = ”
android:text="@={Bean.str,default=defaultvalue}"
事件或方法绑定
这里让button的onclick事件绑定到一个普通的函数上,点击后就执行这个函数,无需再 setOnClickListener
layout:
<data>
<import type="com.zdww.androidframe2020.bean.TestBean"/>
<variable
name="Bean"
type="TestBean" />
<variable
name="MainActivity"
type="com.zdww.androidframe2020.MainActivity" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"
android:gravity="center"
>
<TextView
android:id="@+id/main_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="30dp"
android:text="@={Bean.str,default=defaultvalue}"
android:layout_margin="15dp"
android:paddingStart="15dp"
android:textColor="@color/black"
/>
<Button
android:id="@+id/main_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="button"
android:textSize="30dp"
android:onClick="@{()->MainActivity.HandleStr(Bean)}"
/>
</LinearLayout>
activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding mainBinding= DataBindingUtil.setContentView(this,R.layout.activity_main);
testBean=new TestBean("str");
mainBinding.setBean(testBean);
mainBinding.setMainActivity(this);
}
public void HandleStr(){
testBean.getStr().set("ssss");
}