1. Introduction
View binding was introduced from Android Studio 3.6 . View binding is a new feature that allows you to replace the boring findViewById command with automatically generating binding classes for each XML layout file to simplify code, eliminate bugs, and avoid boilerplate compared to using findViewById. .
2. Use
Note: View binding is available in Android Studio 3.6 version
To use View binding in the module, add viewBinding to the build.gradle file:
1 2 3 4 5 6 7 |
android <span class="token punctuation">{</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> viewBinding <span class="token punctuation">{</span> enabled <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
If you want to skip a file without gen view binding automatically, add the following attribute to each xml file:
1 2 3 4 5 6 |
<span class="token operator"><</span> LinearLayout <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> tools <span class="token operator">:</span> viewBindingIgnore <span class="token operator">=</span> <span class="token string">"true"</span> <span class="token operator">></span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token operator"><</span> <span class="token operator">/</span> LinearLayout <span class="token operator">></span> |
Once viewbinding is enabled, class binding will automatically generated for each XML layout file. The name of the class binding was generated by converting the XML layout file name into a camel case and adding the final Binding suffix.
For example, file xml activityawesome.xml -> ActivityAwesomeBinding
2.1. Using viewbinding in Activity:
To set the instance of the binding class used in the activity, in the onCreate () method, follow these steps:
- Using the inflate () method, an instance of class binding will be created for use in the activity.
- Call to root view reference with getRoot ()
- Pass root view into setContentView () to display the view
1 2 3 4 5 6 7 8 9 |
<span class="token keyword">private</span> lateinit var binding <span class="token operator">:</span> ResultProfileBinding override fun <span class="token function">onCreate</span> <span class="token punctuation">(</span> savedInstanceState <span class="token operator">:</span> Bundle <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span> <span class="token punctuation">.</span> <span class="token function">onCreate</span> <span class="token punctuation">(</span> savedInstanceState <span class="token punctuation">)</span> binding <span class="token operator">=</span> ResultProfileBinding <span class="token punctuation">.</span> <span class="token function">inflate</span> <span class="token punctuation">(</span> layoutInflater <span class="token punctuation">)</span> val view <span class="token operator">=</span> binding <span class="token punctuation">.</span> root <span class="token function">setContentView</span> <span class="token punctuation">(</span> view <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
You can now use the instance of the binding class to reference the elements of the view
1 2 3 |
binding <span class="token punctuation">.</span> name <span class="token punctuation">.</span> text <span class="token operator">=</span> viewModel <span class="token punctuation">.</span> name binding <span class="token punctuation">.</span> button <span class="token punctuation">.</span> setOnClickListener <span class="token punctuation">{</span> viewModel <span class="token punctuation">.</span> <span class="token function">userClicked</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
2.2. Using view binding in Fragment:
To use instance binding class in fragment, in onCreateView () method:
- Using the inflate () method, an instance of class binding will be created for use in fragment.
- Call to root view reference with getRoot ()
- Return root view from the onCreateView () method to display the view
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<span class="token keyword">private</span> var _binding <span class="token operator">:</span> ResultProfileBinding <span class="token operator">?</span> <span class="token operator">=</span> null <span class="token comment">// This property is only valid between onCreateView and</span> <span class="token comment">// onDestroyView.</span> <span class="token keyword">private</span> val binding <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">=</span> _binding <span class="token operator">!</span> <span class="token operator">!</span> override fun <span class="token function">onCreateView</span> <span class="token punctuation">(</span> inflater <span class="token operator">:</span> LayoutInflater <span class="token punctuation">,</span> container <span class="token operator">:</span> ViewGroup <span class="token operator">?</span> <span class="token punctuation">,</span> savedInstanceState <span class="token operator">:</span> Bundle <span class="token operator">?</span> <span class="token punctuation">)</span> <span class="token operator">:</span> View <span class="token operator">?</span> <span class="token punctuation">{</span> _binding <span class="token operator">=</span> ResultProfileBinding <span class="token punctuation">.</span> <span class="token function">inflate</span> <span class="token punctuation">(</span> inflater <span class="token punctuation">,</span> container <span class="token punctuation">,</span> <span class="token boolean">false</span> <span class="token punctuation">)</span> val view <span class="token operator">=</span> binding <span class="token punctuation">.</span> root <span class="token keyword">return</span> view <span class="token punctuation">}</span> override fun <span class="token function">onDestroyView</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> _binding <span class="token operator">=</span> null <span class="token punctuation">}</span> |
You can now use the reference variables of the view:
1 2 3 |
binding <span class="token punctuation">.</span> name <span class="token punctuation">.</span> text <span class="token operator">=</span> viewModel <span class="token punctuation">.</span> name binding <span class="token punctuation">.</span> button <span class="token punctuation">.</span> setOnClickListener <span class="token punctuation">{</span> viewModel <span class="token punctuation">.</span> <span class="token function">userClicked</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
2.3. How is the code generated:
View binding automatically generates 1 class binding for each xml file. When you edit the layout xml file, the automatic gene code will be optimized only for class binding related to that xml file and it will be implemented in memory to ensure everything is as fast as possible. Let’s take a look at an automatic gene file from the xml layout file:
1 2 3 4 5 6 7 8 9 10 |
<span class="token keyword">public</span> <span class="token keyword">final</span> <span class="token keyword">class</span> <span class="token class-name">ActivityAwesomeBinding</span> <span class="token keyword">implements</span> <span class="token class-name">ViewBinding</span> <span class="token punctuation">{</span> <span class="token annotation punctuation">@NonNull</span> <span class="token keyword">private</span> <span class="token keyword">final</span> ConstraintLayout rootView <span class="token punctuation">;</span> <span class="token annotation punctuation">@NonNull</span> <span class="token keyword">public</span> <span class="token keyword">final</span> Button button <span class="token punctuation">;</span> <span class="token annotation punctuation">@NonNull</span> <span class="token keyword">public</span> <span class="token keyword">final</span> TextView subtext <span class="token punctuation">;</span> <span class="token annotation punctuation">@NonNull</span> <span class="token keyword">public</span> <span class="token keyword">final</span> TextView title <span class="token punctuation">;</span> |
View binding will genetically match the type for each view identified by the id assigned to that view.
Layout include:
View binding is also used in include file layout xml
1 2 3 4 5 6 7 8 9 10 |
<span class="token operator"><</span> <span class="token operator">!</span> <span class="token operator">--</span> activity_awesome <span class="token punctuation">.</span> xml <span class="token operator">--</span> <span class="token operator">></span> <span class="token operator"><</span> androidx <span class="token punctuation">.</span> constraintlayout <span class="token punctuation">.</span> widget <span class="token punctuation">.</span> ConstraintLayout <span class="token operator">></span> <span class="token operator"><</span> include android <span class="token operator">:</span> id <span class="token operator">=</span> <span class="token string">"@+id/includes"</span> layout <span class="token operator">=</span> <span class="token string">"@layout/included_buttons"</span> <span class="token operator"><</span> <span class="token operator">/</span> androidx <span class="token punctuation">.</span> constraintlayout <span class="token punctuation">.</span> widget <span class="token punctuation">.</span> ConstraintLayout <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">!</span> <span class="token operator">--</span> included_buttons <span class="token punctuation">.</span> xml <span class="token operator">--</span> <span class="token operator">></span> <span class="token operator"><</span> androidx <span class="token punctuation">.</span> constraintlayout <span class="token punctuation">.</span> widget <span class="token punctuation">.</span> ConstraintLayout <span class="token operator">></span> <span class="token operator"><</span> Button android <span class="token operator">:</span> id <span class="token operator">=</span> <span class="token string">"@+id/include_me"</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> androidx <span class="token punctuation">.</span> constraintlayout <span class="token punctuation">.</span> widget <span class="token punctuation">.</span> ConstraintLayout <span class="token operator">></span> |
Note: tag <include> have id android: id = “@ + id / includes”
1 2 3 4 5 |
public final class ActivityAwesomeBinding implements ViewBinding { ...java @NonNull public final IncludedButtonsBinding includes; |
View binding will automatically reference IncludedButtonsBinding in ActivityAwesomeBinding
3. View binding vs findViewById
View binding has a few points better than findViewById:
- Null safety : Because view binding creates a direct reference to the view, there is no risk like Null Pointer Exception when invalid view ID.
- Type safety : Fileds in each class binding have type matching views with references in the xml file. Therefore, there is no risk with the cast class exception.
4. View binding vs Data Binding
View binding and Data binding both generate automatic class binding for you to use the direct view reference. However, view binding is more noticeable in simple use cases and offers a number of features:
- Faster compile: View binding requires no annotation, so compile time is faster
- Easy to use: View binding doesn’t require a tag for the xml file
Besides, view binding also has some disadvantages compared to data binding:
- View binding does not support layout variables or layout expressions
- View binding does not support two-way data binding
Note: View binding only replaces findViewById, if you want to automatically bind view in layout xml file, you can use view binding with data binding in the same module.
5. View binding vs Kotlin synthetics vs ButterKnife
Above are 3 ways to use view in xml layout file and be used by everyone.
ButterKnife validate nullable / not-null at runtime, the compiler does not check whether you match the layout correctly or not
You should consider using view binding!
Refer:
https://developer.android.com/topic/libraries/view-binding
https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc