ViewBinding
官网
一、配置
build.gradle
文件配置
android {
//...
viewBinding {
enabled = true
}
//或者gradle plugin 7.0以上也可以用如下写法
buildFeatures {
viewBinding true
}
}
如果希望在生成绑定类是忽略某个布局文件,tools:viewBindingIgnore="true"
添加属性到布局文件的根视图中
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="<http://schemas.android.com/apk/res/android>"
xmlns:tools="<http://schemas.android.com/tools>"
android:layout_width="match_parent"
android:layout_height="match_parent"
**tools:viewBindingIgnore="true**">
</androidx.constraintlayout.widget.ConstraintLayout>
二、使用
2.1、创建XML视图文件
当前模块启用视图绑定功能后,系统会为该模块中包含的每个XML生成一个绑定类。每个绑定类均包含对根视图已经具有ID
的所有视图的应用。
系统生成绑定类名称:将XML文件的名字转换为驼峰式大小写,并在末尾添加Binding
一词
假设布局文件名为:fragment_customize.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>"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/firstView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<Button
android:id="@+id/threeView"
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" />
</androidx.constraintlayout.widget.ConstraintLayout>
按照上面的规则说明,系统会给我们生成FragmentCustomizeBinding
文件(文件位置在build/generated/data_binding_base_class_source_out
目录下)。
// Generated by view binder compiler. Do not edit!
package xxx;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.viewbinding.ViewBinding;
import androidx.viewbinding.ViewBindings;
import com.mumu.joker.R;
import java.lang.NullPointerException;
import java.lang.Override;
import java.lang.String;
public final class FragmentCustomizeBinding implements ViewBinding {
@NonNull
private final ConstraintLayout rootView;
@NonNull
public final TextView firstView;
@NonNull
public final Button threeView;
private FragmentCustomizeBinding(@NonNull ConstraintLayout rootView, @NonNull TextView firstView,
@NonNull Button threeView) {
this.rootView = rootView;
this.firstView = firstView;
this.threeView = threeView;
}
@Override
@NonNull
public ConstraintLayout getRoot() {
return rootView;
}
@NonNull
public static FragmentCustomizeBinding inflate(@NonNull LayoutInflater inflater) {
return inflate(inflater, null, false);
}
@NonNull
public static FragmentCustomizeBinding inflate(@NonNull LayoutInflater inflater,
@Nullable ViewGroup parent, boolean attachToParent) {
View root = inflater.inflate(R.layout.fragment_customize, parent, false);
if (attachToParent) {
parent.addView(root);
}
return bind(root);
}
@NonNull
public static FragmentCustomizeBinding 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.
int id;
missingId: {
id = R.id.firstView;
TextView firstView = ViewBindings.findChildViewById(rootView, id);
if (firstView == null) {
break missingId;
}
id = R.id.threeView;
Button threeView = ViewBindings.findChildViewById(rootView, id);
if (threeView == null) {
break missingId;
}
return new FragmentCustomizeBinding((ConstraintLayout) rootView, firstView, threeView);
}
String missingId = rootView.getResources().getResourceName(id);
throw new NullPointerException("Missing required view with ID: ".concat(missingId));
}
}
所生成的绑定类具体三个属性:rootView
、firstView
、threeView
。可以看到没有ID的在绑定类中是不存在引用的。
rootView
属性是私用的,可以通过getRoot()
方法获取根视图的引用
2.2、在Activity中使用
在Actvity
的onCreate()
方法中执行以下步骤:
- 调用绑定类的
inflate()
静态方法,创建绑定类的实例。 - 调用绑定类的
getRoot()
方法或者kotlin的属性语法获取根视图的引用 - 调用Activity的
setContentView()
方法,传递根视图对象 - 后续即可使用绑定类的实例来引用XML任何
具有ID
的视图
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
2.3、在Fragment中使用
在Fragment
的onCreateView()
方法中执行以下步骤:
- 调用绑定类的
inflate()
静态方法,创建绑定类的实例。 - 调用绑定类的
getRoot()
方法或者kotlin的属性语法获取根视图的引用 - 在
onCreateView()
方法中返回根视图 - 后续即可使用绑定类的实例来引用XML任何
具有ID
的视图
private var _binding: FragmentCustomizeBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
_binding = FragmentCustomizeBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
© 版权声明
文章版权归作者所有,未经允许请勿转载,侵权请联系 admin@trc20.tw 删除。
THE END