ViewBinding使用进阶

 ViewBinding基础使用,即在模块得build.gradle配置后自动为布局绑定视图,在《告别findViewById和ButterKnife》中已阐述,那下面的进阶使用可能有些小伙伴还不清楚,那这篇文章我们就扒一扒ViewBinding的进阶使用。

  • 布局中使用include

  • 布局中使用merge

  • Fragment中使用ViewBinding

  • 自定义View使用ViewBinding

 

布局中使用include

新建布局layout_include

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/tv_include"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="来呀,快活呀"/>

</LinearLayout>

然后以include方式添加到MainActivity.xml中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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">

    <include
        layout="@layout/layout_include"/>

    <Button
        android:id="@+id/bt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="haha"
        tools:layout_editor_absoluteX="140dp"
        tools:layout_editor_absoluteY="332dp"
        tools:ignore="MissingConstraints" />

</LinearLayout>

然后在activity中去引用tv_include发现无法引用,这是因为没有给include的布局加id,所以不会将其绑定到视图,故无法引用到tv_include。总结:在布局中使用include需要给include的布局加上id。那如果在layout_include的布局的根布局加上id会怎么样呢?

java.lang.NullPointerException: Missing required view with ID

布局中使用merge

将上面的布局layout_include做以下修改,然后运行一下看看

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/tv_include"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="来呀,快活呀"/>

</merge>

然后你会发现程序秒崩,报错如下

java.lang.NullPointerException: Missing required view with ID: layoutInclude

这是因为merge并不是一个ViewGroup或View,所以无法通过LayoutInflater.inflate()渲染,故无法通过activity的binding直接引用到layout_include.xml。那怎样才能引用到呢?必须在activity中为layout_include.xml指定父节点,具体代码实现如下:

LayoutIncludeBinding includeBinding = LayoutIncludeBinding.bind(binding.getRoot());
includeBinding.tvInclude.setText("来呀,快活呀");

在Fragment中使用ViewBinding

在fragment中使用ViewBinding很简单,只需在onCreateView方法中添加如下代码:​​​​​​​

binding = FragmentMessageBinding.inflate(inflater);
return binding.getRoot();

自定义View中使用ViewBinding

       按照前面的activity和fragment使用,照理在自定义的构造方法中加入下面代码就能完成视图绑定

binding = LayoutTitleBarBinding.inflate(LayoutInflater.from(context));

然而这样操作之后运行应用发现自定义View不显示,为什么呢?我们来看一下源码:​​​​​​​

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

  @NonNull
  public static LayoutTitleBarBinding inflate(@NonNull LayoutInflater inflater,
      @Nullable ViewGroup parent, boolean attachToParent) {
    View root = inflater.inflate(R.layout.layout_title_bar, parent, false);
    if (attachToParent) {
      parent.addView(root);
    }
    return bind(root);
  }

从源码中可发现,inflate(LayoutInflater.from(context))并不会将当前布局生成的view加入到根布局中,所以在界面中无法显示。修改成下面这样

binding = LayoutTitleBarBinding.inflate(LayoutInflater.from(context), this, true);

运行应用发现完美呈现,跟我们不使用ViewBinding是一样的。

欢迎大家关注我个人公众号

 

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值