为什么要用DataBinding
是否因为一个页面中大量使用findViewById 而烦恼?
是否因为一个简单的UI 控件的代码,还要在Activity 中写,是否可以在xml 中写?
Databinding 就是为了解决这个问题而产生的.
如何使用
修改build.gradle
android {
.//添加下面配置
buildFeatures {
dataBinding true
}
}
修改布局文件格式
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<fragment
android:id="@+id/fr1"
android:name="com.sim.testViewmodel.BlankFragment1"
android:layout_width="match_parent"
android:layout_height="100dp"
/>
<fragment
android:id="@+id/fr2"
android:name="com.sim.testViewmodel.BlankFragment2"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_below="@id/fr1" />
<TextView
android:id="@+id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/fr2"
/>
<TextView
android:id="@+id/text2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/text1"
/>
<TextView
android:id="@+id/text3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/text2"
/>
<TextView
android:id="@+id/text4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/text3"
/>
</RelativeLayout>
</layout>
根目录添加<layout> 标签即可
修改Activity
ActivityTestViewModel2Binding activityTestViewModel2Binding = DataBindingUtil.setContentView(this,R.layout.activity_test_view_model2);
Student zs = new Student();
zs.name = "张三";
zs.note = "1111";
zs.scool = "一中";
zs.sex = "男";
activityTestViewModel2Binding.text1.setText(zs.name);
activityTestViewModel2Binding.text2.setText(zs.note);
activityTestViewModel2Binding.text3.setText(zs.scool);
activityTestViewModel2Binding.text4.setText(zs.sex);
ActivityTestViewModel2Binding 这个名字和布局文件的名字有关,就是布局文件名字的大写+Binding,,,下图所示,一目了然.
运行发现赋值生效.这是最基本的用法.
其他用法
1,布局文件直接获取对象的值,并且赋值
正常情况下我们赋值文本文件是不是要向上面的代码方式 setText()
//..........
activityTestViewModel2Binding.text1.setText("");
DataBinding 简化后
布局
为了看着方便,我们只看差异部分
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
//对象添加
<variable
name="stu"
type="com.sim.testViewmodel.Student" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
//....
android:text="@{stu.name}"
/>
<TextView
//....
android:text="@{stu.note}"
/>
<TextView
//....
android:text="@{stu.scool}"
/>
<TextView
//....
android:text="@{stu.sex}"
/>
</RelativeLayout>
</layout>
Activity
// activityTestViewModel2Binding.text1.setText(zs.name);
// activityTestViewModel2Binding.text2.setText(zs.note);
// activityTestViewModel2Binding.text3.setText(zs.scool);
// activityTestViewModel2Binding.text4.setText(zs.sex);
//DataBingding 效果
activityTestViewModel2Binding.setStu(zs);
对比发现,Activity 工作少了好多,,,我觉得这个用处不大,而且 感觉有点坑,有问题,调试都不方便.....
2,布局中引用静态类
感觉越来越臃肿,,都不想学习这个了,不过既然有就记录下吧,,就当成存在即合理吧
如果我们在xml 中text 文本需要转换,这个就需要java 处理下了.xml 中如何做呢
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
//导入类
<import type="com.sim.testViewmodel.MyUtil"/>
<variable
name="stu"
type="com.sim.testViewmodel.Student" />
</data>
//.....
<TextView
//调用
android:text="@{MyUtil.getScoolLevel(stu.scool)}"
/>
</layout>
工具类
public class MyUtil {
public static String getScoolLevel(String scrool){
switch (scrool){
case "一中":
return "好学校";
default:
return "一般学校";
}
}
}
这个只适合工具类的调用方式.
3,Button 监听
这个说实话,我也没感觉有啥用处.....
监听类
public class ButtonListener {
private Context context;
public ButtonListener(Context context) {
this.context = context;
}
public void buttonclick(View view){
Toast.makeText(context, "button click", Toast.LENGTH_SHORT).show();
}
}
布局文件
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="com.sim.testViewmodel.MyUtil"/>
<variable
name="stu"
type="com.sim.testViewmodel.Student" />
//导入class
<variable
name="button"
type="com.sim.testViewmodel.ButtonListener" />
</data>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/text4"
android:text="button"
//点击监听
android:onClick="@{button.buttonclick}"
/>
</RelativeLayout>
</layout>
Activity
activityTestViewModel2Binding.setButton(new ButtonListener(this));
4,二级页面使用DataBinding
对于二级和一级大致相同,关键在于引用的地方.
一级页面布局
<?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"
>
<data>
<import type="com.sim.testViewmodel.MyUtil"/>
<variable
name="stu"
type="com.sim.testViewmodel.Student" />
<variable
name="button"
type="com.sim.testViewmodel.ButtonListener" />
</data>
<include
android:layout_below="@+id/button"
layout="@layout/layout_second"
//添加对象引用的位置
app:stu="@{stu}"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
</layout>
可以看到我们加了 xmlns:app="http://schemas.android.com/apk/res-auto" app 的命名空间,方便去属性 app:stu="@{stu}"
二级页面
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
>
//参考一级页面的对象添加
<data>
<variable
name="stu"
type="com.sim.testViewmodel.Student" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{stu.scool}"
/>
</RelativeLayout>
</layout>
使用方式同一级一样.
这是比较常用的,还有好多其他用法,后续学习了,在更新
问题
很多人第一次配置<layout> 标签后,发现app 就运行不起来了,是因为studio 版本和gradle 的配置太低了,
1,可以升级studio ,在Help->Check For Updates
2,配置gradle版本.File->Project Struct 修改配置
参考
https://developer.android.com/jetpack/androidx/releases/databinding?hl=zh-cn