2.2.3.Architecture components_View Binding

参考

https://developer.android.com/topic/libraries/view-binding

简介

简单来说就是来代替findViewById的。

配置

在AndroidStudio3.6及以上版本可用,

在模块的build.gradle中加入:

android {
  ...
  viewBinding {
    enabled = true
  }
}

其他不用配置,编译时自动生成对应的绑定类。

绑定类的名字是由xml的名字生成的,比如result_profile.xml,那么生成的绑定类就是ResultProfileBinding。

使用

生成的绑定类中会有布局根view和有id的view的引用,

在Activity中使用

private ResultProfileBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ResultProfileBinding.inflate(getLayoutInflater());
    View view = binding.getRoot();
    setContentView(view);
}

然后就可以用这个绑定对象直接访问view。

在Fragment中使用

private ResultProfileBinding binding;

@Override
public View onCreateView (LayoutInflater inflater,  ViewGroup container,  Bundle savedInstanceState) {
    binding = ResultProfileBinding.inflate(inflater, container, false);
    View view = binding.getRoot();
    return view;
}

@Override
public void onDestroyView() {
    binding = null;
}

不想用

在布局根view上加入tools:viewBindingIgnore="true"

<LinearLayout
        ...
        tools:viewBindingIgnore="true" >
    ...
</LinearLayout>

和findViewById的不同

与使用findViewById相比,视图绑定具有重要的优势:

  • l 空安全性:由于视图绑定会创建对view的直接引用,因此不会因无效的视图ID而导致空指针异常的风险。

此外,当view仅在布局的某些配置中存在时,在绑定类中包含其引用的字段将用@Nullable标记。

  • l 类型安全性:每个绑定类中的字段具有与其在XML文件中引用的view匹配的类型。 这意味着没有类强制转换异常的风险。

这些差异意味着布局和代码之间的不兼容性将导致 build失败 在编译时 而不是 在运行时。

和DataBinding的不同

Data Binding和View Binding都会生成的绑定类,

view binding生成的绑定类直接实现ViewBinding接口,

而DataBinding生成的绑定类是继承ViewDataBinding,而ViewDataBinding实现了ViewBinding接口。

view binding只是简单的findViewById,

而Data binding除了findViewById外,还有数据绑定的功能。

include

activity_databinding.xml

<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"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <include
        android:id="@+id/databinding1"
        layout="@layout/databinding1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <include
        android:id="@+id/no_binding"
        layout="@layout/list_item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/databinding1" />

</androidx.constraintlayout.widget.ConstraintLayout>

上边布局有两个includedatabinding1是一个绑定布局,而第二个是普通布局,都加上了id

不管是什么类型的布局,我们都可以通过activity_databindingviewbinding对象直接访问引用的绑定对象,而不用手动获取

databinding1就是直接访问绑定布局对象,第二个是直接访问它的viewbinding对象。

Databinding1Binding databinding1Binding = activityDataBindingBinding.databinding1;
ListItemBinding noBinding = activityDataBindingBinding.noBinding;

分析

那么看一下生成的ViewBinding类就能明白具体是怎么操作的:

@NonNull
public static ActivityDatabindingBinding 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.
  String missingId;
  missingId: {
    View databinding1 = rootView.findViewById(R.id.databinding1);
    if (databinding1 == null) {
      missingId = "databinding1";
      break missingId;
    }
    Databinding1Binding databinding1Binding = Databinding1Binding.bind(databinding1);
    View noBinding = rootView.findViewById(R.id.no_binding);
    if (noBinding == null) {
      missingId = "noBinding";
      break missingId;
    }
    ListItemBinding noBindingBinding = ListItemBinding.bind(noBinding);
    TextView tv = rootView.findViewById(R.id.tv);
    if (tv == null) {
      missingId = "tv";
      break missingId;
    }
    return new ActivityDatabindingBinding((ConstraintLayout) rootView, databinding1Binding,
        noBindingBinding, tv);
  }
  throw new NullPointerException("Missing required view with ID: ".concat(missingId));
}

可以看到生成的viewbinding类自动帮我们做了获取绑定对象的步骤。

猜你喜欢

转载自www.cnblogs.com/muouren/p/12368546.html