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不显示,相信原因大家以经知道了,跟上面在布局中使用merge一样,那改成下面这样呢?
binding = LayoutTitleBarBinding.inflate(LayoutInflater.from(context));
addView(binding.getRoot());
运行应用发现UI无法填充满布局,最后修改成下面这样
binding = LayoutTitleBarBinding.inflate(LayoutInflater.from(context), this, true);
运行应用发现完美呈现,那比较一下第二和第三的方式,第二种只是给自定义控件一个父节点,而第三种方式则让自定义view以ViewGroup的方式加入到父节点,也就是第三种方式的第二个参数的意义,跟我们不使用ViewBinding是一样的。
欢迎大家关注我个人公众号