1.app模块下的build.gradle文件的Android块中,添加:
dataBinding {
enabled = true
}
2.对生成的layout文件,使用Alt+Enter,转化为binding layout:
public class User{
private ObservableField<String> name ;
private ObservableField<Integer> age ;
private ObservableField<String> picUrl ;
private ObservableField<String> introduce ;
public User() {
}
public User(String name, int age, String picUrl, String introduce) {
this.name = new ObservableField<>(name);
this.age = new ObservableField<>(age);
this.picUrl = new ObservableField<>(picUrl);
this.introduce = new ObservableField<>(introduce);
}
... //getter setter
}
如果要实现单、双向绑定,这里的getter 和 setter是不能少的,不能少的,不然会失效。同时,写法是如下:
public ObservableField<String> getName() {
return name;
}
public void setName(ObservableField<String> name) {
this.name = name;
}
不是这种写法:
public String getName(){
return name.get();
}
public void setName(String name){
this.name.set(name);
}
或者使用下面的方法:
<data>
<variable
name="User"
type="com.xxx.model.User" />
</data>
使用如下:
<TextView
android:id="@+id/textName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{User.name}" />
<TextView
android:id="@+id/textAge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf(User.age)}" />
<EditText
android:id="@+id/editIntroduce"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:hint="@string/edit_introduce_hint"
android:text="@={User.introduce}" />
注意:
定义事件处理类,类似MVP中的P(这里定义在Activity中):
public class UserPresenter {
public void onUpdateIntroduce(User user) {
Log.e(TAG, "onUpdateIntroduce: " + user.toString());
}
}
在xml中引入:
<data>
<variable
name="User"
type="com.xxx.model.User" />
<variable
name="UserPresenter"
type="com.xxx.view.MainActivity.UserPresenter" />
</data>
使用:
<Button
android:id="@+id/btnSure"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:onClick="@{()->UserPresenter.onUpdateIntroduce(User)}"
android:text="@string/btn_sure" />
或者使用@UserPresenter::onUpdateIntroduce(User)
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
User user = new User("John", 20, "https://www.xxx.com/img/my_head.jpg", "Hello World");
binding.setUser(user);
binding.setUserPresenter(new UserPresenter());
定义一个处理自定义属性的类和方法:
public class ImageViewAdapter {
@BindingAdapter(value = "url", requireAll = false)
public static void setImageUrl(ImageView imageView, String url){
Glide.with(BaseApplication.getContext()).load(url).into(imageView);
}
使用:
<ImageView
android:id="@+id/imagePic"
android:layout_width="100dp"
android:layout_height="100dp"
bind:url="@{User.picUrl}" />
bind声明:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
这样就可以使用了,但是这个时候的url,如果填入值,是不会有值匹配显示的,类似这样:
可以通过在style中定义一个declare-styleable:
<declare-styleable name="ImageView">
<attr name="url"/>
</declare-styleable>
然后再看:
不用指定attr的format,否则一样不显示,但是使用app命名空间就会显示。这个设置不会影响使用,只是少了自动匹配model的属性,以及按住Ctrl跳转的功能。
通过上面的例子可以看到,这里存在2个问题。
下一篇文章会介绍经过封装的形式,相对高级一点点