版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/crazyman2010/article/details/54314674
XXXBinding类
这个类是数据绑定类,是和布局文件对应的,假设布局文件为activity_xxx,编译的时候会自动生成一个类:
应用包名.databinding.ActivityXxxBinding.java
这个类继承了android.databinding.ViewDataBinding,它是实现数据和界面通信的桥梁。
类中成员变量:
views : 为布局文件每个定义了id的view生成了一个public final成员变量
variables:为布局文件中每个variable节点生成一个private变量
listeners: 为布局文件中的事件响应函数生成回调方法
类中方法:
构造方法
inflate和bind方法
variable的getter/setter方法
XXXBinding实例化
要实现数据和界面的通信,需要实例化这个类,但是通常并不直接使用构造方法实例化,在Activity中一般使用下面的方法实例化:
ActivityXxxBinding binding=DataBindingUtil.setContentView(this, R.layout.activity_xxx);
DataBindingUtil.setContentView 这个函数做了三步操作:
inflate操作,创建布局文件对应的view对像
setContentView操作,将view加入window
bind操作,创建ActivityXxxBinding 对像
public static <T extends ViewDataBinding> T setContentView(Activity activity, int layoutId,
DataBindingComponent bindingComponent) {
activity.setContentView(layoutId); //调用activity的setContentView设置好布局文件,这是inflate操作
View decorView = activity.getWindow().getDecorView();
ViewGroup contentView = (ViewGroup) decorView.findViewById(android.R.id.content);
return bindToAddedViews(bindingComponent, contentView, 0, layoutId);
}
private static <T extends ViewDataBinding> T bindToAddedViews(DataBindingComponent component,
ViewGroup parent, int startChildren, int layoutId) {
final int endChildren = parent.getChildCount();
final int childrenAdded = endChildren - startChildren;
if (childrenAdded == 1) {
final View childView = parent.getChildAt(endChildren - 1);
return bind(component, childView, layoutId); //这是绑定操作
} else {
final View[] children = new View[childrenAdded];
for (int i = 0; i < childrenAdded; i++) {
children[i] = parent.getChildAt(i + startChildren);
}
return bind(component, children, layoutId);
}
}
bind操作最终调用了ActivityXxxBinding.bind(view, bindingComponent)操作,然后调用了:
new ActivityXxxBinding(bindingComponent, view) 创建了ActivityXxxBinding 对像。
但是在有些场景中并不能用setContentView这个方法,比如在fragment中,在recyclerview中,所以databing提供了其他实例化方法:
//inflate R.layout.activity_xxx.xml
//如果root不为空且attachToRoot为true的话将view添加到root里面
// 执行bind操作
public static ActivityXxxBinding inflate(android.view.LayoutInflater inflater, android.view.ViewGroup root, boolean attachToRoot);
//inflate R.layout.activity_xxx.xml
//执行bind操作
public static ActivityXxxBinding inflate(android.view.LayoutInflater inflater);
//执行bind操作
public static ActivityRegisterBinding bind(android.view.View view);
//DataBindingUtil提供的函数:
//inflate 指定的布局文件
//如果root不为空且attachToRoot为true的话将view添加到root里面
//执行bind操作
public static <T extends ViewDataBinding> T inflate(LayoutInflater inflater, int layoutId, @Nullable ViewGroup parent, boolean attachToParent);
了解一下ActivityXxxBinding构造函数:
public ActivityRegisterBinding(android.databinding.DataBindingComponent bindingComponent, View root) {
super(bindingComponent, root, 3);
final Object[] bindings = mapBindings(bindingComponent, root, 13, sIncludes, sViewsWithIds);
this.loginBtn1 = (android.widget.Button) bindings[11];
//... ...
setRootTag(root);
// listeners
mCallback4 = new android.databinding.generated.callback.OnClickListener(this, 4);
//... …
invalidateAll();
}
主要的工作是:解析root对像,初始化view变量,初始化listener变量。
XXXBinding常用方法
public View getRoot():返回创建binding对像时inflated的view.
public void executePendingBindings(): 立即刷新数据到view.
public abstract boolean setVariable(int variableId, Object value):设置variable的数据