使用上面的代码实现了UI的更新你就满足了?其实官方为我们提供了更加简便的方式,使User继承BaseObservable,代码如下
public class User extends BaseObservable {
private String firstName;
private String lastName;
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@Bindable
public String getFirstName() {
return this.firstName;
}
@Bindable
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
notifyPropertyChanged(BR.lastName);
}
public void setFirstName(String firstName) {
this.firstName = firstName;
notifyPropertyChanged(BR.firstName);
}
}
只要user发生变化,就能达到改变UI的效果。在MainActivity中只要调用以下代码
user.setFirstName("Com");
有了BaseObservable就够了?不不不,我比较懒,不想写那么多@Bindable和notifyPropertyChanged。万一里面有几十个属性,那不写哭起来?而且还有可能写丢了。
Data Binding的开发者贴心得为我们准备了一系列的ObservableField,包括: ObservableBoolean, ObservableByte, ObservableChar, ObservableShort, ObservableInt, ObservableLong, ObservableFloat,ObservableDouble, 以及 ObservableParcelable看看它们的用法
ObservableField的使用
1、创建User2
public class User2 {
public final ObservableField firstName = new ObservableField<>();
public final ObservableField lastName = new ObservableField<>();
public final ObservableInt age = new ObservableInt();
public final ObservableBoolean isStudent = new ObservableBoolean();
}
这类里面没有Get/Set。
2、布局文件
3、MainActivity中
mUser2 = new User2();
binding.setUser2(mUser2);
mUser2.firstName.set("Mr");
mUser2.lastName.set("Bean");
mUser2.age.set(20);
mUser2.isStudent.set(false);
这里new了一个User2对象后,直接就绑定了。之后只要mUser2中的数据发生变化,UI也会随之更新。
除了这几个Map跟List也是必不可少的,Data Binding为我们提供了 ObservableArrayMap和ObservableArrayList。
ObservableArrayMap的使用
ObservableArrayMap user = new ObservableArrayMap<>();
user.put("firstName", "Google");
user.put("lastName", "Inc.");
user.put("age", 17);
…
ObservableArrayList的使用
ObservableArrayList user = new ObservableArrayList<>();
user.add("Google");
user.add("Inc.");
user.add(17);
…
在布局中使用中文时,编译无法通过。
android:text='@{user2.isStudent?"学生":"非学生"}'
感谢吕檀溪同学的解决方案:
这是java环境的问题,在系统环境变量中增加一个变量,变量名为: JAVA_TOOL_OPTIONS, 变量值为:-Dfile.encoding=UTF-8,保存。要重启一次电脑,中文就解决了,但是在某些地方,编译的时候控制台会出现部分乱
在RecyclerView或ListView中使用
前面说了那么多基础的用法,可还是不能达到我们的需求。几乎在每个app中都有列表的存在,RecyclerView或ListView,从上面所说的似乎还看不出Data Binding在RecyclerView或ListView中是否也能起作用。(用屁股想也知道,Google的开发团对怎么可能会犯这么低级的错误)。下面以RecyclerView为例子:
1、直接看Item的布局(user_item.xml):
2、RecyclerView的数据绑定是在Adapter中完成的,下面看看Adapter(这里使用了一个Adapter,如果你在使用的时候发现RecyclerView的动画没了,去这里寻找答案)
public class MyAdapter extends RecyclerView.Adapter {
private List mData = new ArrayList<>();
public MyAdapter(List data) {
this.mData = data;
}
@Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return MyHolder.create(LayoutInflater.from(parent.getContext()), parent);
}
@Override
public void onBindViewHolder(MyHolder holder, int position) {
holder.bindTo(mData.get(position));
}
@Override
public int getItemCount() {
if (mData == null)
return 0;
return mData.size();
}
static class MyHolder extends RecyclerView.ViewHolder {
private UserItemBinding mBinding;
static MyHolder create(LayoutInflater inflater, ViewGroup parent) {
UserItemBinding binding = UserItemBinding.inflate(inflater, parent, false);
return new MyHolder(binding);
}
private MyHolder(UserItemBinding binding) {
super(binding.getRoot());
this.mBinding = binding;
}
public void bindTo(User2 user) {
mBinding.setUser2(user);
mBinding.executePendingBindings();
}
}
}
3、最后在布局和MainActivity中的使用跟平时的用法一样
布局中加入RecyclerView:
MainActivity中:
List data = new ArrayList<>();
for (int i = 0; i < 20; i++) {
User2 user2 = new User2();
user2.age.set(30);
user2.firstName.set("Micheal " + i);
user2.lastName.set("Jack " + i);
data.add(user2);
}
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(
this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(new MyAdapter(data));
这样就可以了。
不过,在自动生成的ActivityMainBinding中,我们可以看到根据RecyclerView的id,会自动生成一个recyclerView。

所以在MainActivity中,我们可以不用findViewById,直接使用binding.recyclerView。
LinearLayoutManager layoutManager = new LinearLayoutManager(
this, LinearLayoutManager.VERTICAL, false);
binding.recyclerView.setLayoutManager(layoutManager);
binding.recyclerView.setAdapter(new MyAdapter(data));
来看看效果吧:

RecyclerView