使用方法:
1、配置
graldel文件
dataBinding{ enabled true }
XML文件
<data> <variable name="users" type="com.example.myapplication.databinding.User" /> //对应继承BaseObservable接口的类 </data>
<TextView android:id="@+id/tv1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{users.name}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />
类使用BaseObservable 和 Bindable注解
public class User extends BaseObservable { private String name; private String password;
@Bindable public String getName() { return name; }
}
使用:
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); binding.setUsers(new User("yanyang", "124"));
源码分析:
初始化
代码使用:ActivityMainBindingImpl binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
源码说明: DataBindingUtils.java private static <T extends ViewDataBinding> T bindToAddedViews(DataBindingComponent component, ViewGroup parent, int startChildren, int layoutId) { 。............. return bind(component, children, layoutId); } }
实现类 DataBinderMapperImpl.java, 对xml进行解析,每个view生成一个对象
@Override public ViewDataBinding getDataBinder(DataBindingComponent component, View view, int layoutId) { ...... final Object tag = view.getTag(); if(tag == null) { throw new RuntimeException("view must have a tag"); } switch(localizedLayoutId) { case LAYOUT_ACTIVITYMAIN: { if ("layout/activity_main_0".equals(tag)) { return new ActivityMainBindingImpl(component, view);
ActivityMainBindingImpl.java mapBindings解析XML存入数组,
监听注册
ActivityMainBindingImpl.java
updateRegistration(localFieldId, observable, CREATE_PROPERTY_LISTENER); 参数localFiledID 就是BF文件对应的 0 1 2.... observable为子类
CREATE_PROPERTY_LISTENER
private static final CreateWeakListener CREATE_PROPERTY_LISTENER = new CreateWeakListener() { @Override public WeakListener create(ViewDataBinding viewDataBinding, int localFieldId) { return new WeakPropertyListener(viewDataBinding, localFieldId).getListener(); } };
protected void registerTo(int localFieldId, Object observable, CreateWeakListener listenerCreator) { if (observable == null) { return; } WeakListener listener = mLocalFieldObservers[localFieldId]; if (listener == null) { listener = listenerCreator.create(this, localFieldId); mLocalFieldObservers[localFieldId] = listener; if (mLifecycleOwner != null) { listener.setLifecycleOwner(mLifecycleOwner); } } listener.setTarget(observable); } 说明:mLocalFieldObservers数组,存放着 WeakPropertyListener, 改对象里存着了WeakListener对象,这个对象持有ViewDataBinding的引用,也持有VM的引用,
最后setTarget方法调用了WeakPropertyListener的addListener方法,也就是调用了VM的addOnPropertyChangedCallback
监听可用于后续的更新。
更新流程
-
ActivityMainBindingImpl实现类 notifyPropertyChanged
- baseObservable.java
public void notifyPropertyChanged(int fieldId) { synchronized (this) { if (mCallbacks == null) { return; } } mCallbacks.notifyCallbacks(this, fieldId, null); }
- CallBackRegistry.java
public synchronized void notifyCallbacks(T sender, int arg, A arg2) { mNotificationLevel++; notifyRecurse(sender, arg, arg2); ....... }
-
notifyRemainder
-
private void notifyCallbacks(T sender, int arg, A arg2, final int startIndex, final int endIndex, final long bits) { long bitMask = 1; for (int i = startIndex; i < endIndex; i++) { if ((bits & bitMask) == 0) { mNotifier.onNotifyCallback(mCallbacks.get(i), sender, arg, arg2); } bitMask <<= 1; } }
- PropertyChangeRegistry.java
public void onNotifyCallback(OnPropertyChangedCallback callback, Observable sender, int arg, Void notUsed) { callback.onPropertyChanged(sender, arg); }
7. ViewDataBinding.java 内部静态类 WeakPropertyListener
@Override public void onPropertyChanged(Observable sender, int propertyId) { ViewDataBinding binder = mListener.getBinder(); if (binder == null) { return; } Observable obj = mListener.getTarget(); if (obj != sender) { return; // notification from the wrong object? } binder.handleFieldChange(mListener.mLocalFieldId, sender, propertyId); }
8.ActivityMainBindingImpl.java
protected boolean onFieldChange(int localFieldId, Object object, int fieldId) { switch (localFieldId) { case 0 : return onChangeUsers((com.example.myapplication.databinding.User) object, fieldId); } return false; }
//通过二进制的运算,判断内容是否更新。
private boolean onChangeUsers(com.example.myapplication.databinding.User Users, int fieldId) { if (fieldId == BR._all) { synchronized(this) { mDirtyFlags |= 0x1L; } return true; 。。。。。
}
8.notify之后 requestRebind 刷新UI