“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