DEV Community

Cover image for View Binding in Android.
Samuel Wahome
Samuel Wahome

Posted on

View Binding in Android.

If you're familiar with native Android app development with either Java or Kotlin, then you've probably needed a means by which to write code that interacts with your views, which would have probably been written in an XML layout file. Well, to make things simpler, that's where View Binding comes right in.

For starters, according to the official Android developer resource:

View binding is a feature that allows you to more easily write code that interacts with views.

Once view binding is enabled in a module, it generates a binding class for each XML layout file present in that module. An instance of a binding class contains direct references to all views that have an ID in the corresponding layout.
In most cases, view binding replaces findViewById. This simply means that you are essentially able to get rid of the excess boilerplate code. 
Without wasting any more time, let's get straight to the code.

GIF

Setting it up.

Fun fact: You don't need to include any extra libraries to enable view binding, as it's built into the Android Gradle Plugin starting with the versions shipped from Android Studio 3.6 onwards. To enable view binding, configure viewBinding in your module-level build.gradle file.

android {
    ...
    buildFeatures {
        viewBinding true
    }
}
Enter fullscreen mode Exit fullscreen mode

Once enabled for a project, view binding will generate a binding class for all of your layouts automatically. The name of the binding class is generated by converting the name of the XML file to Pascal case and adding the word "Binding" to the end.
Once this is done, you can use the binding class whenever you inflate layouts such as Fragment, Activity, or even a RecyclerView Adapter (or ViewHolder).

View Binding in an Activity.

To set up an instance of the binding class for use with an activity, you have to perform the following in the activity's onCreate() method:

  1. Call the static inflate() method included in the generated binding class. This creates an instance of the binding class for the activity to use.
  2. Get a reference to the root view by either calling the getRoot() method or using Kotlin property syntax.
  3. Pass the root view to setContentView() to make it the active view on the screen.
private SampleLayoutBinding binding;
private TextView categoryName;
private Button submitButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = SampleLayoutBinding.inflate(getLayoutInflater());
    View view = binding.getRoot();
    setContentView(view);
    init();
}
private void init() {
    categoryName = binding.categoryName;
    submitButton = binding.submitButton;
}
Enter fullscreen mode Exit fullscreen mode

Once this is done, you can now use the instance of the binding class to reference and utilize any of the views:

categoryName.setText(categoryList.get(category_index).getName());
submitButton.setOnClickListener(v -> submitTest());

Enter fullscreen mode Exit fullscreen mode

View Binding in Fragments.

To set up an instance of the binding class for use with a fragment, you have to perform the following in the fragment's onCreateView() method:

  1. Call the static inflate() method included in the generated binding class. This creates an instance of the binding class for the fragment to use.
  2. Get a reference to the root view by either calling the getRoot()method or using Kotlin property syntax.
  3. Return the root view from the onCreateView() method to make it the active view on the screen.
private SampleLayoutBinding binding;
private TextView categoryName;
private Button submitButton;

@Override
public View onCreateView (LayoutInflater inflater,
                          ViewGroup container,
                          Bundle savedInstanceState) {
    binding = SampleLayoutBinding.inflate(inflater, container, false);
    View view = binding.getRoot();
    init();

    return view;
}

private void init() {
    categoryName = binding.categoryName;
    submitButton = binding.submitButton;
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    binding = null;
}
Enter fullscreen mode Exit fullscreen mode

Once this is done, you can now use the instance of the binding class to reference and utilize any of the views:

categoryName.setText(categoryList.get(category_index).getName());
submitButton.setOnClickListener(v -> submitTest());
Enter fullscreen mode Exit fullscreen mode

ViewBinding in a RecyclerView Adapter(or ViewHolder).

To set up an instance of the binding class for use with a RecyclerView Adapter, you need to pass the generated binding class object to the holder class constructor. In your example, you may have recipe_card XML file for RecyclerView item and the generated class is RecipeCardBinding . 
Therefore, you need to use the onCreateViewHolder to pass the generated binding class to the ViewHolder class.

@NonNull
@Override
public CategoryAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    RecipeCardBinding itemBinding = RecipeCardBinding .inflate(LayoutInflater.from(parent.getContext()), parent, false);
    return new ViewHolder(itemBinding);
}
Enter fullscreen mode Exit fullscreen mode

Once the above steps have been completed, you may then use the holder class like this so you can use these fields in onBindViewHolder.

static class ViewHolder extends RecyclerView.ViewHolder {
    private TextView textView;
    private ImageView imageView; 

    MyViewHolder(RecipeCardBinding itemBinding) {
        super(itemBinding.getRoot());
        imageView = itemBinding.img ;
        textView = itemBinding.txt ;
    }
}
Enter fullscreen mode Exit fullscreen mode

All in all, View Binding is a pretty good solution when it comes to binding views as they are:

  • Type-safe: Properties are always correctly typed based on the views in the layout. So if you put a TextView in the layout, view binding will expose a TextView property.
  • Null-safe: This is applicable for layouts defined in multiple configurations. View binding will detect if a view is only present in some configurations and create a @Nullable property.

And since the generated binding classes are regular Java classes with Kotlin-friendly annotations, you can use view binding from both the Java programming language and Kotlin.

Differences between findViewById(), Butterknife, Kotlin Synthetics, DataBinding, and View Binding.

Courtesy of https://wajahatkarim.com/

Resources.

In case you may need further information on View Binding or any of its alternatives, then these links will be of much help:


That was indeed all that I have to share for now✌. To all readers, cheers to code🥂, and have a blessed day.

Discussion (0)