DataBinding(含ViewBinding)(二)绑定原理

上篇已经讲了 ViewBindingDataBinding的使用,下面看一下它们之间的关系。

// ViewBinding 
> Task :app:dataBindingMergeDependencyArtifactsDebug UP-TO-DATE
> Task :app:dataBindingMergeGenClassesDebug UP-TO-DATE
> Task :app:dataBindingGenBaseClassesDebug UP-TO-DATE

// DataBinding
> Task :databinding:dataBindingMergeDependencyArtifactsDebug UP-TO-DATE
> Task :databinding:dataBindingMergeGenClassesDebug UP-TO-DATE
> Task :databinding:dataBindingGenBaseClassesDebug UP-TO-DATE
> Task :databinding:dataBindingTriggerDebug UP-TO-DATE
复制代码

从上面task 可以看出 ViewBinding属于 DataBindig。接下来将分别讲解 ViewBindingDataBinding的原理。其中用到示例在 BindingSample 可以查到

DataBinding 包含三篇博客:

DataBinding(含ViewBinding)(一)使用

DataBinding(三)构建过程分析

一、ViewBinding的绑定原理

build.gradle中配置了如下:

buildFeatures{
    viewBinding = true
}
复制代码

即引入了ViewBinding,AS插件会将 xxx.xml生成 XxxBindig.java代码,在xml文件的根布局中设置 tools:viewBindingIgnore="true"则表示忽略该文件,不生成 XxxBinding.java文件

1.1 生成的代码

生成的 XxxBinding.java在该目录下:
app\build\intermediates\javac\debug\classes\com\zbt\viewbindingtest\databinding

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
        
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="noId"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tv_text" />

</androidx.constraintlayout.widget.ConstraintLayout>
复制代码

生成的 ActivityMainBinding.java:

public final class ActivityMainBinding implements ViewBinding {
  @NonNull
  private final ConstraintLayout rootView;
  @NonNull
  public final TextView tvText;

  private ActivityMainBinding(@NonNull ConstraintLayout rootView, @NonNull TextView tvText) {
    this.rootView = rootView;
    this.tvText = tvText;
  }

  @Override
  @NonNull
  public ConstraintLayout getRoot() {
    return rootView;
  }

  @NonNull
  public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater) {
    return inflate(inflater, null, false);
  }

  @NonNull
  public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater,
      @Nullable ViewGroup parent, boolean attachToParent) {
    // 1.通过布局填充器获取rootView,组合View需要传递的Parent等参数
    View root = inflater.inflate(R.layout.activity_main, parent, false);
    if (attachToParent) {
      parent.addView(root);
    }
    return bind(root);
  }

  @NonNull
  public static ActivityMainBinding bind(@NonNull View rootView) {
    // The body of this method is generated in a way you would not otherwise write.
    // This is done to optimize the compiled bytecode for size and performance.
    // 2.通过rootView.findViewById 获取到相应的View
    int id;
    missingId: {//不知道这个是什么
      id = R.id.tv_text;
      TextView tvText = rootView.findViewById(id);
      if (tvText == null) {
        break missingId;
      }

      // 3.将所有查找的View,通过构造方法传递给ActivityMainBinding
      return new ActivityMainBinding((ConstraintLayout) rootView, tvText);
    }
    String missingId = rootView.getResources().getResourceName(id);
    throw new NullPointerException("Missing required view with ID: ".concat(missingId));
  }
}
复制代码

可以看到 ActivityMainBinding 实现了 ViewBinding接口,提供 getRoot()返回的是 xml文件的根布局。获取ActivityMainBinding流程如下:

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享