DataBinding系列五、XXXBinding

版权声明:本文为博主原创文章,未经博主允许不得转载。 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的数据

猜你喜欢

转载自blog.csdn.net/crazyman2010/article/details/54314674