ViewDataBinding分析
每个Fragment或Activity的布局开启DataBinding后都会生成一个ViewDataBinding子类。我们来分析其中关键源码
1. ActivityMainBinding 的初始化
ActivityMainBinding进行相关初始化设置,绑定数据与DataBinding的关联
private ActivityMainBindingImpl(androidx.databinding.DataBindingComponent bindingComponent, View root, Object[] bindings) {
//1. ActivityMainBinding 布局界面初始化,包括相关的值赋予
invalidateAll();
}
/**
* 初始化布局,并对控件的设值赋值
*/
@Override
public void invalidateAll() {
synchronized(this) {
mDirtyFlags = 0x10L;
}
// 请求重新绑定,主要是对控件的各值显示进行变动
requestRebind();
}
2. 指定变量赋值
public void setLiveData(@Nullable com.xuanyuan.databindinganalysis.MyObservableField LiveData) {
updateRegistration(0, LiveData);
this.mLiveData = LiveData;
synchronized(this) {
mDirtyFlags |= 0x1L;
}
notifyPropertyChanged(BR.liveData);
super.requestRebind();
}
public void setClick(@Nullable android.view.View.OnClickListener Click) {
this.mClick = Click;
synchronized(this) {
mDirtyFlags |= 0x4L;
}
notifyPropertyChanged(BR.click);
super.requestRebind();
}
3. 通知更新指定变量
// 控件的各值进行确定赋予
@Override
public boolean setVariable(int variableId, @Nullable Object variable) {
boolean variableSet = true;
else if (BR.liveData == variableId) {
setLiveData((com.xuanyuan.databindinganalysis.MyObservableField) variable);
} else {
variableSet = false;
}
return variableSet;
}
4. 变量Change,通知UI刷新
@Override
protected void executeBindings() {
...
if ((dirtyFlags & 0x11L) != 0) {
androidx.databinding.adapters.TextViewBindingAdapter.setText(this.etName, liveDataGet);
}
if ((dirtyFlags & 0x10L) != 0) {
// api target 1
androidx.databinding.adapters.TextViewBindingAdapter.setTextWatcher(this.etName, null,null, etNameandroidTextAttrChanged);
}
}
当我们使用"@={}"双向绑定符时,观测ViewBindingIml代码。
1.常规双向绑定
private androidx.databinding.InverseBindingListener etNameandroidTextAttrChanged = new androidx.databinding.InverseBindingListener() {
@Override
public void onChange() {
java.lang.String callbackArg_0 = androidx.databinding.adapters.TextViewBindingAdapter.getTextString(etName);
java.lang.String userName = null;
boolean userJavaLangObjectNull = false;
com.xuanyuan.databindinganalysis.User user = mUser;
userJavaLangObjectNull = (user) != (null);
if (userJavaLangObjectNull) {
user.setName(((java.lang.String) (callbackArg_0)));
}
}
};
TextViewBindingAdapter.setTextWatcher(this.etName, null, null, null, etNameandroidTextAttrChanged);
其实这种双向绑定只是调用了 view.addTextChangedListener(newValue),对内容变动后的监听操作处理,源码中自动帮我们处理了。
2. Observable双向绑定
val livaValue = MyObservableField()
override fun onClick(v: View?) {
if (v?.id == R.id.btnLogin) {
val value = Math.random() * 1300
livaValue.set(value.toString())
}
}
<EditText
android:id="@+id/etName"
android:layout_width="match_parent"
android:text="@={liveData}"
android:inputType="text" />
1.当调用livaValue.set()时,阅读源码会发现有更新回调,最终执行ViewBinding的executeBindings()方法
@Override
protected void executeBindings() {
...
}
2.更新调用后,EditText中的值变化,会触发TextChangedListener再次调用livaValue.set(value.toString()。此时EditText中的值变化中的值不再变化