Imagine that you are working on an android studio project and it contains lots of views. How many times that you should write findViewByID() !!!. Moreover, how many times your app crashed due to view null pointer exception. So that, View Binding in android studio solves theses issues. Furthermore, this feature allows you more easily to write code that interacts with Views. As, once it enabled it generates a binding class for each XML layout file. Simply, the main_activity.xml file if related to MainActivity.java file. So, after enabling View Binding a binding class for main activity created and enables you to access all views inside main_activity.xml file. That happens because when the binding class created it contains direct references for all View that has ID in the corresponding layout file.
Note: view binding is available in android studio 3.6 canary11+.
View Binding VS findViewByID()
Furthermore, view binding has the following important advantages over findViewByID().
- Null Safety: There is no risk of a null pointer exception because view binding provides direct references for views that has ID in the layout file.
- Type Safety: Because, fields that created by binding class have types matching the view they reference in XML file. So that, there is no risk of class cast exception.
How to setup View Binding in Android Studio
In order to use view binding we need at first to enable it in gradle file. So, we need to edit module level gradle file and use the following feature inside android {}. After that click sync.
android {
buildFeatures {
viewBinding true
}
}
After synchronization we can use view binding in Activities, Fragment, and Also Adapters.
Using View Binding in Activities
When view binding enabled the binding class for each XML layout file generated. Moreover, the name of binding class created by converting the nname of XML layout file Camel case and adding the word “Binding” to the end. For example:
- activity_main.xml file: will generate “ActivityMainBindig” class.
- activity_startup.xml file: will generate “ActivityStartupBinding” class.
- activity_user.xml file: will generate “ActivityUserBinding” class.
So, if we have in activity_user.xml as the following:
<LinearLayout ... >
<TextView android:id="@+id/name" />
<ImageView android:cropToPadding="true" />
<Button android:id="@+id/button"
android:background="@drawable/rounded_button" />
</LinearLayout>
Each binding class contains references to the root view and all views that have an ID. In order to set up an instance of the binding class for use with an activity as following.
public class UserActivity extends AppCompatActivity { private ActivityUserBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /*Call the staticinflate()
method included in the generated binding class. This creates an instance of the binding class for the activity to use.*/ binding = ActivityUserBinding.inflate(getLayoutInflater()); //Get a reference to the root view by either calling thegetRoot()
//Pass the root view to setContentView() to make it the active view on the screen. setContentView(binding.getRoot()); } }
You can now use the instance of the binding class to reference any of the views:
binding.text.setText("Android Hands"); binding.button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(MainActivity.this,SecondActivity.class)); } });
Using View Binding in Fragments
Moreover, we can use view binding in the fragment by using the following steps in the code.
public class BlankFragment extends Fragment { private FragmentBlankBinding binding; public BlankFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { /* Call the staticinflate()
method included in the generated binding class. This creates an instance of the binding class for the fragment to use. */ binding = FragmentBlankBinding.inflate(inflater,container,false); // Get a reference to the root view by either calling thegetRoot()
method binding.fragmentTextView.setText("Hello From Blank Fragment"); /*Return the root view from theonCreateView()
method to make it the active view on the screen.*/ return binding.getRoot(); } @Override public void onDestroyView() { super.onDestroyView(); binding = null; } }
Using View Binding in RecyclerView
The following example show how to use view binding RecyclerView. As, once you create the row layout of the recyclerview a new binding class genereted with the name of the row layout. In this example the name of the row layout XML file has name “row_layout.xml”, so the generated binding class will take the name “RowLayoutBinding”.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/textView" android:text="Text" android:padding="16sp" android:layout_margin="5dp"/> </LinearLayout>
And the Recycler Adapter class will be as the following.
public class BindingRecyclerAdapter extends RecyclerView.Adapter<BindingRecyclerAdapter.MyViewHolder> { List<String > stringList; public BindingRecyclerAdapter(List<String> stringList) { this.stringList = stringList; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { RowLayoutBinding rowLayoutBinding = RowLayoutBinding.inflate(LayoutInflater.from(parent.getContext()),parent,false); return new MyViewHolder(rowLayoutBinding); } @Override public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { holder.rowLayoutBinding.textView.setText(""); } @Override public int getItemCount() { return stringList.size(); } class MyViewHolder extends RecyclerView.ViewHolder{ RowLayoutBinding rowLayoutBinding; public MyViewHolder (@Nullable RowLayoutBinding rowLayoutBinding){ super(rowLayoutBinding.getRoot()); this.rowLayoutBinding= rowLayoutBinding; } } }