写这篇文章是为了Android课小论文,现在选摘部分,如果老师看到不要认为我论文抄这篇
Android中的页面布局和很多基本设定是靠xml来描述的,所以当我们从第一个Activity开始写逻辑控制的时候,第一步基本上都是使用findViewById,如果页面的布局较为负载,各种控件较多,就会造成findViewById需要写很多,代码耦合很高,因此说Activity基本上都是View和Controller的合体,既要负责视图的显示又要加入控制逻辑,承担的功能过多,代码量大也就不足为奇。现在使用Data Binding就可以较好的降低代码的耦合度。
简单的一个例子,假设有一个User类,包括name,现在要在TextView中显示,传统的写法自然是findViewById绑定TextView,然后创建User实例,对TextView进行setText操作,但是如果很多地方都使用这一个实例的话,就会造成要对很多TextView进行setText操作,现在就使用Data Binding解决这个问题。
- Module中开启Data Binding
dataBinding {
enabled = true
}
- User类
public class User extends BaseObservable {
private String name;
public User(String name) {
this.name = name;
}
@Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
}
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="daniellee.databindingdemo.User" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@={user.name}" />
<Button
android:id="@+id/updateName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="update" />
</LinearLayout>
</layout>
- MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
final User user = new User("Daniel");
binding.setUser(user);
binding.updateName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
user.setName("White");
}
});
}
}
首先是BaseObservable类,在User类中最关键的代码就是set方法中的notifyPropertyChanged(BR.name),查看源码可以看到调用了基类中一个实例对象PropertyChangeRegistry的notifyCallbacks方法,PropertyChangeRegistry的注释为Utility class for
managing Observable callbacks.这也就说明了这个方法使用来处理回调的。同时方法参数有一个BR,查看源码可以看到是一个新类,没有其他方法,只有几个int值,查阅文档可以知道,这个类和R文件差不多,是自动生成的,里面的内容也就是id值而已,这就是框架做的工作,本身工作并没有省掉。接下来是layout,新型的写法多了data标签,主要是做数据的部分,和对象实例化没有什么实质上的区别,只是写法采用了xml格式而已,这样在@={}中就可以直接使用这个实例了。
最后是Activity,不同于原先的findViewById,这里使用的是DataBindingUtil类的静态方法setContentView,查看源码可以看到,其实内部做的工作也就是findViewById,并没有什么太大的秘密,这个方法返回一个对象,类型为ActivityMainBinding,但是查看方法返回类型是一个泛型T extends ViewDataBinding,在Intellij IDEA中查看源码,将直接跳转到layout的xml文件,查阅文档可知,这也是框架自动为我们生成的,生成类型名字规则上面已经介绍。紧接着可以看到调用了binding的setUser方法,这也是自动生成的,名字就是我们在xml中的variable的名字,如果有其他variable同样会生成其他的set方法,设定完以后xml中的user和在Activity中的user就对应起来了,这就完成了数据的绑定任务。使用按钮来改变name值可以看到效果,可以同样注意到按钮也是通过binding调用的,所以ActivityMainBinding其实把xml的东西以一个类来描述,这样我们需要做的工作就是面向binding,而不是xml,实现了代码的解耦,但是还要认识到,这只是框架为我们做的工作,本身其实还是这些工作,并没有因此而减少。
Data Binding主要帮助我们的是减少对控件的直接操作,降低代码的耦合,将代码的核心专注在逻辑控制,少掺入页面的更新,降低代码的耦合,更多其他的用法参考文档。