Explanation of the new view binding tool ViewBinding in Android Studio 3.6

  • 2021-11-24 02:51:23
  • OfStack

Preface

In the process of Android development, we always need to get ViewId in XML layout, so as to assign values to it for display. In the early days, we can only use findViewById, which will lead to a lot of template code. Around 2013, Jake Wharton, the great god of Android, opened the framework of Butter Knife, which is convenient for developers to obtain ViewId through Bind ("viewid"). In the past two years, due to Google's support for Kotlin, we began to use Android Kotlin extensions. Importing the layout file in the file directly references viewId. No need to do other additional operations, the most convenient.

At present, Google has added a new view binding tool ViewBinding in Android Studio 3.6 Canary 11 and later.

Let's take a look at the specific use.

Use of ViewBinding

Many of our current projects are developed using modularity. ViewBinding is also very clever and can be enabled by module. If you want to enable ViewBinding in a module, you need to add the following configuration in the module's build. gradle:


android {
 ...
 viewBinding {
  enabled = true
 }
}

If the developer does not want to generate an binding class for a layout file during use, you can add the following properties to the root view of the layout:


<LinearLayout
  ...
  tools:viewBindingIgnore="true" > 
 ...
</LinearLayout>

When the module turns on the view binding function, the system will generate the corresponding binding class for every XML file in the module. Every 1 binding class contains references to the root view and all views that define ID.

The name generation rule of binding class is to end the name of XML file according to hump naming rule plus Binding.

For example, our activity_main. xml file.


<LinearLayout ... >
 <TextView android:id="@+id/name" />
 <ImageView android:cropToPadding="true" />
 <Button android:id="@+id/button"
  android:background="@drawable/rounded_button" />
</LinearLayout>

Then the production binding class name is ActivityMainBinding. This class has two fields: one is TextView named name, and the other is Button named button. ImageView in this layout does not have ID, so there is no reference to it in the bound class.

Each binding class also contains an getRoot () method that provides a direct reference to the root view of the layout file. In this example, the getRoot () method in the ActivityMainBinding class returns the LinearLayout root view.

The automatically generated binding class is not complicated, mainly two inflate overloaded methods and one bind method. The reference to viewId we obtained is carried out in bind method, and the related view is actually obtained through findViewById internally.

We usually set the layout file through setContentView ("layoutId"), but with ViewBinding we need to set layout as follows:


class MainActivity : AppCompatActivity() {
 
 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
 
  val binding = ActivityMainBinding.inflate(layoutInflater)
  setContentView(binding.root)
  // Get name Perform an assignment 
  binding.name.text = "viewBinding"
 }
}

So you can use it directly. Isn't it very simple?

However, it should be noted that if our layout file is divided into layout and layout-land, there may be different viewId when we define the layout. If findViewById or Butter Knife is used, it will definitely be abnormal.

When we use ViewBinding, the binding class makes relevant judgments for us. Use @ Nullable and @ NonNull annotations to tell developers which view might be empty. And the related fixation description is added to the view which may be empty.


/**
 * This binding is not available in all configurations.
 * <p>
 * Present:
 * <ul>
 * <li>layout/</li>
 * </ul>
 *
 * Absent:
 * <ul>
 * <li>layout-land/</li>
 * </ul>
 */
 @Nullable
 public final TextView mAppTv;

Remind developers to pay attention to exception handling when using it.

Summarize

At present, the functions of ViewBinding are not perfect, for example, when inClude tag is used in XML, view cannot be referenced. But on the whole, it's been very good. Compared with findViewById and Butter, Knife is much more convenient. Moreover, ViewBinding does not have the problems of type conversion and null pointer exception in the process of using it. Because it's all defined in the binding class. Developers can use it directly. Compared with Android Kotlin extensions, I think both of them are similar. I can't say who is better. Compared with databinding, the data binding library only handles the use of < layout > The data-bound layout created by the code. It has limitations.

At present, Jake Wharton also adds the following sentence to Butter Knife open source library:

Attention: Development on this tool is winding down. Please consider switching to view binding in the coming months.

Supplement: Differences from findViewById

View binding has important advantages over using findViewById:
Null security: Because the view binding creates a direct reference to the view, there is no risk of null pointer exceptions due to an invalid view ID. In addition, when the view exists only in some configurations of the layout, the fields that contain its references in the bound class will be used with @ Nullable
• Type safety: Fields in each bound class have a type that matches the view they reference in the XML file. This means that there is no risk of class cast exceptions.

These differences mean that incompatibility between layout and code will cause compilation to fail at compile time rather than run time.

Difference from data binding Library

Both view binding and data binding libraries generate binding classes that can be used to directly reference views. However, there are obvious differences:
The ES 156EN ES 157EN library only deals with data-bound layouts created using tags.
• ES 159EN ES 160EN does not support layout variables or layout expressions and therefore cannot be used to bind layouts to ES 161EN data.


Related articles: