参考【Android】DataBinding库(MVVM设计模式)
入门
在module的build.gradle配置:
android {
....
dataBinding {
enabled =true
}
}
Bean对象
public class User {
private String name;
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
布局
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="com.yolo.myapplication.User" />
</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="@{user.name}" />
</RelativeLayout>
</layout>
注意:这里跟平时的布局有点不同。需要在原布局基础上包装一层layout节点,并在自己的同级增加data节点。
data:声明了需要用到的对象,type用于指定对象路径,name是对此对象重新命名,方便使用属性。
可以在TextView中的看到android:text=”@{user.name}”。
绑定数据
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
ContentMainBinding binding = DataBindingUtil.setContentView(this, R.layout.content_main);
User user = new User();
user.setName("我是名字");
binding.setUserBean(user);
}
生成的DataBinding名与绑定的布局名称保持一致的。即假如布局是R.layout.activity_main,那么类名就ActivityMainBinding。
布局中variable节点下的name值影响着binding的方法名。即如果布局中name值是userBean,那么binding的方法名就是setUserBean。
如果是include的布局,则需要执行具体的layout资源。
<!-- activity_main.xml 包含了content_main,如果需要绑定content_main的UI,则应该制定此布局-->
<include
layout="@layout/content_main"/>
扩展
命名
修改DataBinding名,只需在data节点下增加class属性即可。
<data class="ContentBinding">
<variable
name="user"
type="com.yolo.myapplication.User" />
</data>
导包
type的值还可以使用导包的形式
<data class="ContentBinding">
<import type="com.yolo.myapplication.User"/>
<variable
name="user"
type="User" />
</data>
遇到相同的类名, 可以取别名
<data>
<import type="com.example.gavin.databindingtest.User" alias="User"/>
<import type="com.example.gavin.mc.User" alias="mcUser"/>
<variable name="user" type="User"/>
<variable name="mcUser" type="mcUser"/>
</data>
用到的对象也需要导包
<data>
<import type="android.view.View"/>
</data>
...
<TextView
...
android:visibility="@{user.isStudent ? View.VISIBLE : View.GONE}"
/>
表达式
- 形式1:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{userBean.girl?View.VISIBLE:View.GONE}" />
- 形式2
注意:外层的双引号需要改成单引号
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{userBean.girl?"Girl": "Other"}' />
运算符??
除了常用的操作法,另外还提供了一个 null 的合并运算符号 ??,这是一个三目运算符的简便写法。
contact.lastName ?? contact.name
相当于
contact.lastName != null ? contact.lastName : contact.name
绑定图片
绑定图片与绑定文本略有不同,前者需要使用BindingAdapter注解,声明一个属性。
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data class="ContentBinding">
<variable
name="imgUrl"
type="String" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop"
app:image="@{imgUrl}" />
</RelativeLayout>
</layout>
定义显示图片的静态方法【必须是静态方法】
@BindingAdapter("image")
public static void showImage(ImageView iv, String url){
Glide.with(iv.getContext()).load(url).into(iv);
}
如果不是静态方法,则抛如下异常
Caused by: java.lang.IllegalStateException: Required DataBindingComponent is null in class ContentBinding.
A BindingAdapter in com.yolo.myapplication.MainActivity is not static and requires an object to use, retrieved from the DataBindingComponent.
If you don't use an inflation method taking a DataBindingComponent, use DataBindingUtil.setDefaultComponent or make all BindingAdapter methods static.
绑定,设置Url地址即可
binding.setImgUrl("http://image.uczzd.cn/14094444771339725257.png?id=0");
点击事件
布局
<data class="ContentBinding">
<variable
name="handle"
type="com.yolo.myapplication.MainActivity" />
</data>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录"
android:onClick="@{handle.login}"/>
响应事件
//参数View必须有,必须是public,参数View不能改成对应的控件,只能是View,否则编译不通过
public void login(View view) {
Toast.makeText(this, "登录", Toast.LENGTH_LONG).show();
}
绑定
//1.响应事件在Activity中
binding.setHandle(this);
//2.响应事件在其他类中,传递类的对象
binding.setHandle(new Other());
//待续
版权声明:本文为Jason847原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。