“This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!”
Why is it recommended that you replace findViewById and ButterKnife with a ViewBinding? Because it’s too good. It’s too high. Used it once, fell in love with it, never wanted to go back. True. Don’t believe you see below!
define
ViewBinding is a component of Google’s Jetpack library that is designed to bind views instead of findViewById. Viewbinding will according to the XML file to generate a corresponding binding classes, such as our XML file: activity_login_layout. The XML generated by the binding class is ActivityLoginLayoutBinding such a class. Call the view component in our XML directly from the generated binding class at the time of use, without findViewById and without declaring the component. Let’s take a look at our integration and projects to quickly understand.
integration
First we will introduce viewBind in our build. Gradld project
/ / introduce ViewBinding
viewBinding {
viewBinding = true
}
Copy the code
Then we can use ViewBinding in our code
code
A login page, activity_login_layout.xml, is created
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
tools:viewBindingIgnore="false"
android:padding="16dp">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_login_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Login"
android:textColor="@color/design_default_color_primary_variant"
android:textSize="19sp" />
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/et_login_account"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="10dp"
android:hint="User name"
android:paddingStart="10dp"
android:paddingEnd="10dp" />
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/et_login_pwd"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="10dp"
android:hint="Password"
android:paddingStart="10dp"
android:paddingEnd="10dp" />
<Button
android:id="@+id/btn_login"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="20dp"
android:background="@color/design_default_color_secondary"
android:text="Login"
android:textSize="20dp" />
<TextView
android:id="@+id/tv_find_pwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:text="Get your password back."
android:textColor="@android:color/holo_red_dark"
android:textSize="16sp" />
</LinearLayout>
Copy the code
So let’s look at findViewById and get the ID and set the click event and so on
class LoginActivity2 : AppCompatActivity(R.layout.activity_login_layout) {
Declare the control first
lateinit var etAccount: EditText
lateinit var etPwd: EditText
lateinit var btnLogin: Button
override fun onCreate(savedInstanceState: Bundle?). {
super.onCreate(savedInstanceState)
initView()
}
private fun initView(a) {
// Initialize the findViewById controller in sequence
etAccount = findViewById(R.id.et_login_account)
etPwd = findViewById(R.id.et_login_pwd)
btnLogin = findViewById(R.id.btn_login)
btnLogin.setOnClickListener {
var accountInfo = etAccount.text
var accountPwd = etPwd.text
if(! TextUtils.isEmpty(accountInfo)) {if(! TextUtils.isEmpty(accountPwd)) { Log.e("ping"."Perform the login operation: Username:$accountInfoPassword:$accountPwd")}else {
Log.e("ping"."Please enter your password")}}else {
Log.e("ping"."Please enter your user name.")}}}}Copy the code
Let’s take a look at the code that uses ViewBinding
class LoginActivity : AppCompatActivity() {
private lateinit var binding: ActivityLoginLayoutBinding
override fun onCreate(savedInstanceState: Bundle?). {
super.onCreate(savedInstanceState)
binding = ActivityLoginLayoutBinding.inflate(layoutInflater)
val view = binding.root;
setContentView(view)
initView()
}
private fun initView(a) {
binding.btnLogin.setOnClickListener {
var accountInfo = binding.etLoginAccount.text
var accountPwd = binding.etLoginPwd.text
if(! TextUtils.isEmpty(accountInfo)) {if(! TextUtils.isEmpty(accountPwd)) { Log.e("ping"."Perform the login operation: Username:$accountInfoPassword:$accountPwd")}else {
Log.e("ping"."Please enter your password")}}else {
Log.e("ping"."Please enter your user name.")}}}}Copy the code
Whether very intuitive, do not need to declare controls, also do not need the findViewById directly with ActivityLoginLayoutBinding binding classes. Operation can, is not very Nice. This time you said, so I do not know that is that control how to do? We’ll look at ActivityLoginLayoutBinding class code:
public final class ActivityLoginLayoutBinding implements ViewBinding {
@NonNull
private final LinearLayout rootView;
@NonNull //android:id="@+id/btn_login"
public final Button btnLogin; // Declare controls named after the ID hump we defined in XML
@NonNull //android:id="@+id/et_login_account"
public final AppCompatEditText etLoginAccount;
@NonNull //android:id="@+id/et_login_pwd"
public final AppCompatEditText etLoginPwd;
@NonNull // android:id="@+id/tv_find_pwd"
public final TextView tvFindPwd;
@NonNull
public final AppCompatTextView tvLoginTitle;
private ActivityLoginLayoutBinding(@NonNull LinearLayout rootView, @NonNull Button btnLogin, @NonNull AppCompatEditText etLoginAccount, @NonNull AppCompatEditText etLoginPwd, @NonNull TextView tvFindPwd, @NonNull AppCompatTextView tvLoginTitle) {
this.rootView = rootView;
this.btnLogin = btnLogin;
this.etLoginAccount = etLoginAccount;
this.etLoginPwd = etLoginPwd;
this.tvFindPwd = tvFindPwd;
this.tvLoginTitle = tvLoginTitle;
}
@NonNull
public LinearLayout getRoot() {
return this.rootView;
}
@NonNull
public static ActivityLoginLayoutBinding inflate(@NonNull LayoutInflater inflater) {
return inflate(inflater, (ViewGroup)null.false);
}
@NonNull
public static ActivityLoginLayoutBinding inflate(@NonNull LayoutInflater inflater, @Nullable ViewGroup parent, boolean attachToParent) {
View root = inflater.inflate(2131427356, parent, false);
if (attachToParent) {
parent.addView(root);
}
return bind(root);
}
@NonNull
public static ActivityLoginLayoutBinding bind(@NonNull View rootView) {
int id = 2131230807;
Button btnLogin = (Button)ViewBindings.findChildViewById(rootView, id);
if(btnLogin ! =null) {
id = 2131230876;
AppCompatEditText etLoginAccount = (AppCompatEditText)ViewBindings.findChildViewById(rootView, id);
if(etLoginAccount ! =null) {
id = 2131230877;
AppCompatEditText etLoginPwd = (AppCompatEditText)ViewBindings.findChildViewById(rootView, id);
if(etLoginPwd ! =null) {
id = 2131231121;
TextView tvFindPwd = (TextView)ViewBindings.findChildViewById(rootView, id);
if(tvFindPwd ! =null) {
id = 2131231122;
AppCompatTextView tvLoginTitle = (AppCompatTextView)ViewBindings.findChildViewById(rootView, id);
if(tvLoginTitle ! =null) {
return new ActivityLoginLayoutBinding((LinearLayout)rootView, btnLogin, etLoginAccount, etLoginPwd, tvFindPwd, tvLoginTitle);
}
}
}
}
}
String missingId = rootView.getResources().getResourceName(id);
throw new NullPointerException("Missing required view with ID: ".concat(missingId)); }}Copy the code
In fact, ViewBinding automatically states the control for us and executes fingViewById. We only need to use binding. BtnLogin and so on
How to bind views in an Activity
To use view binding in an Activity, perform the following steps in the onCreate() method:
- Call the static inflate() method contained in the generated binding class. This creates an instance of the bound class for the Activity to use.
- Get a reference to the root view either by calling the getRoot() method or by using the Kotlin attribute syntax.
- Pass the root view to setContentView() to make it the active view on the screen.
private lateinit var binding: ActivityLoginLayoutBinding
override fun onCreate(savedInstanceState: Bundle?). {
super.onCreate(savedInstanceState)
binding = ActivityLoginLayoutBinding.inflate(layoutInflater)
val view = binding.root;
setContentView(view)
}
Copy the code
You can then use any View defined on the View, for example:
binding.btnLogin.setOnClickListener {
var accountInfo = binding.etLoginAccount.text
var accountPwd = binding.etLoginPwd.text
if(! TextUtils.isEmpty(accountInfo)) {if(! TextUtils.isEmpty(accountPwd)) { Log.e("ping"."Perform the login operation: Username:$accountInfoPassword:$accountPwd")}else {
Log.e("ping"."Please enter your password")}}else {
Log.e("ping"."Please enter your user name.")}}}Copy the code
Use view binding in the Fragment
Using view binding in the Fragment, first perform the following steps in the onCreateView() method:
- Call the static inflate() method contained in the generated binding class. This creates an instance of the bound class for use by the Fragment.
- Get a reference to the root view either by calling the getRoot() method or by using the Kotlin attribute syntax.
- Return the root view from the onCreateView() method, making it the active view on the screen.
class LoginFragment : Fragment() {
private lateinit var binding: ActivityLoginLayoutBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup? , savedInstanceState:Bundle?).: View? {
binding = ActivityLoginLayoutBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView(a) {
super.onDestroyView()
null.also { it -> binding = it }
}
}
Copy the code
And then we’re happy to use the view that we’ve defined on our view
binding.btnLogin.setOnClickListener {
// Perform the login operation
}
Copy the code
conclusion
The obvious advantage over findViewById is that it’s a lot less code, a lot simpler to use, and a lot less useless. Also,
- Null security: Since view binding creates a direct reference to the view, there is no risk of a Null pointer exception being thrown because the view ID is invalid. In addition, if the view appears only in some configurations of the layout, the fields in the binding class that contain its references are marked with the @Nullable tag.
- Type safety: The fields in each binding class have types that match the views they refer to in the XML file. This means that there is no risk of class transformation exceptions occurring.
advantages
- Faster compilation: View bindings do not need to process comments, so compile time is shorter
- Easy to use: View binding does not require a specially tagged XML layout file, so adoption is faster in applications. When view binding is enabled in a module, it is automatically applied to all layouts for that module.
disadvantages
- View bindings do not support layout variables or layout expressions and therefore cannot be used to declare dynamic interface content directly in AN XML layout file.
- View binding does not support bidirectional data binding.
That’s all about ViewBinding. If you think it’s good, click “like”. thank you