siera
siera

Reputation: 563

How to use view binding in Android

I have been using findViewById and then ButterKnife to bind views. Recently, I came across this article and am not quite sure how to use it.

I tried doing it but it does not seem to work in Android Studio 3.4.2

val binding = MainActivityBinding.inflate(layoutInflater)
setContentView(binding.root)

then afterwards using these values, as an example :

binding.button....
binding.textView....

Upvotes: 55

Views: 158187

Answers (11)

Umut ADALI
Umut ADALI

Reputation: 1196

View binding is only available in Android Studio 3.6 Canary 11+. Firstly, you upgrade Android studio with android gradle plugin version 3.6.0-alpha11+ (you can use beta both of them for now, stable version not yet released but you can use beta) then add below code in build.gradle

android {
        viewBinding.enable = true
}

Now you can use like we used with data binding like that:

private lateinit var binding: ActivityMainBinding

@Override
fun onCreate(savedInstanceState: Bundle) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    binding.textView.text = "Hello World"
}

that's it.

Upvotes: 17

SaadAAkash
SaadAAkash

Reputation: 3193

ViewBindings are introduced at this moment of this talk at Google IO/19. It will be available with Android Studio 3.6 and as you mentioned, you're using Android Studio 3.4.2 so it's not working. Read the ViewBindings portion in this article for more references.

Upvotes: 4

Abubakar Khalid
Abubakar Khalid

Reputation: 139

:--------------------------------------This is for Kotlin--------------------------------------:

You need to follow two steps:

1) Add viewBinding in your project's Module:

buildFeatures{
        viewBinding true
    }

enter image description here

2) Add binding to your Activity Class:

private lateinit var binding: ActivitySplashBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivitySplashBinding.inflate(layoutInflater)
        setContentView(binding.root)

enter image description here

Upvotes: 7

Rehan Khan
Rehan Khan

Reputation: 1291

In most cases, view binding replaces findViewById.

Java: Add this in Gradle file

android {
...
    buildFeatures {
        viewBinding true
    }
}

Kotlin

android {
    ...
    buildFeatures {
        viewBinding = true
    }
}

If you want a layout file to be ignored while generating binding classes, add the tools:viewBindingIgnore="true" attribute to the root view of that layout file:

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

Use view binding in activities

Kotlin

private lateinit var binding: ResultProfileBinding
    
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ResultProfileBinding.inflate(layoutInflater)
    val view = binding.root
    setContentView(view)
}

Java

private ResultProfileBinding binding;
    
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ResultProfileBinding.inflate(getLayoutInflater());
    View view = binding.getRoot();
    setContentView(view);
}

You can now use the instance of the binding class to reference any of the views:

Kotlin

binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }

Java

binding.getName().setText(viewModel.getName());
binding.button.setOnClickListener(new View.OnClickListener() {
    viewModel.userClicked()
});

view binding in fragments

Kotlin

private var _binding: ResultProfileBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
    
override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
    ): View? {
        _binding = ResultProfileBinding.inflate(inflater, container, false)
        val view = binding.root
        return view
    }
    
override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
}

Java

private ResultProfileBinding binding;
    
@Override
public View onCreateView (LayoutInflater inflater,
                              ViewGroup container,
                              Bundle savedInstanceState) {
    binding = ResultProfileBinding.inflate(inflater, container, false);
    View view = binding.getRoot();
    return view;
}
    
@Override
public void onDestroyView() {
    super.onDestroyView();
    binding = null;
}

You can now use the instance of the binding class to reference any of the views:

Kotlin

kotlinbinding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }

Java

binding.getName().setText(viewModel.getName());
binding.button.setOnClickListener(new View.OnClickListener() {
    viewModel.userClicked()
});

Upvotes: 25

Ronik Limbani
Ronik Limbani

Reputation: 917

in kotlin

The important note is view binding is only available for android studio 3.6+. implement view binding in the project you can follow the below steps.

Step 1: upgrade your Gradle version(3.6.1+) in the build.gradle (Project Level) file.

   dependencies {
            classpath 'com.android.tools.build:gradle:7.0.3' 
    }

Step 2: Add this line to your build.gradle (App Level) file in android{}

 buildFeatures {
        viewBinding = true
    }

Step 3: Add this code (Depend on Your Activity name).

class MainActivity : AppCompatActivity() {

 private lateinit var binding: ActivityMainBinding

 
 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

    binding = ActivityMainBinding.inflate(layoutInflater)
    val view = binding.root //you can use directly setContentView(binding.root)
    setContentView(view) 
    binding.textview.text="Hii" 

}

or you can achieve the above functionality in this code. I personally prefer to goes to the second one.

class MainActivity : AppCompatActivity() {

    private val binding by lazy {

        ActivityMainBinding.inflate(layoutInflater)
    }


   override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        binding.textview.text="Hii" 

    }
}

Upvotes: 2

Rohit S
Rohit S

Reputation: 794

View Binding ViewBinding is available from Android Studio 3.6 and above

  1. It is used to bind the views to the code in other words we can simply say it replaces findViewById in android which reduces the boilerplate code.

  2. we can use view binding whenever you inflate layouts such as Fragment, Activity, or RecyclerView Adapter.

  3. Once view binding is enabled it will automatically generate a binding class for all the XML layouts in android project and no needed to make any changes in our xml layouts manually.

  4. We can enable view binding in the module-level build.gradle

    android {
    ...
    buildFeatures {
    viewBinding true
    }
    }

activity_simple_view_binding_example.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".SimpleViewBindingExample">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:id="@+id/demoTv"/>


</LinearLayout>

SimpleViewBindingExample.java

public class SimpleViewBindingExample extends AppCompatActivity {

    private ActivitySimpleViewBindingExampleBinding activitySimpleViewBindingExampleBinding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activitySimpleViewBindingExampleBinding = ActivitySimpleViewBindingExampleBinding.inflate(getLayoutInflater());
        setContentView(activitySimpleViewBindingExampleBinding.getRoot());

        activitySimpleViewBindingExampleBinding.demoTv.setText("View Binding is simple");

    }
}

Upvotes: 2

Marek Kondracki
Marek Kondracki

Reputation: 1427

I recommend use like this:

private val viewBinding: ADarkModeBinding by lazy { ADarkModeBinding.inflate(layoutInflater) }

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(viewBinding.root)
}

Upvotes: 0

Sujeet Mishra
Sujeet Mishra

Reputation: 209

As a beginner, If you want to learn to implement the Data Binding in your Android project.

then simply follow these steps:-

1:- First open up your Gradel Scripts Folder and locate build.gradel Module file and paste this code inside android project.

 dataBinding {
        enabled = true
    }

plugins {
    id 'com.android.application'
    id 'kotlin-android'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.example.implementing_data_binding"
        minSdkVersion 19
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    dataBinding {
        enabled = true
    }
}

dependencies {

    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
    implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

then simply in your XML file encapsulate your current layout in a new parent layout tag and shift name-space declaration from current layout to newly created parent layout

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">
    
<androidx.coordinatorlayout.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/myId"
        android:layout_width="wrap_content"
        android:layout_height="34dp"
        android:layout_marginLeft="150sp"
        android:layout_marginTop="300sp"
        android:text="Hello world!" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

2:- Go to your view and assign an id to it:- android:id="@+id/textHere"

3:- Then simply go inside your corresponding activity file and below the Activity class initialization put

lateinit var binding: ActivityMainBinding;

Note- the word ActivityMainBinding is just a combination of your file where the view exists along with the + 'Binding'

ex:- File name: acvity_main.kt -------> ActivityMainBinding

And inside the onCreate function just below the super constructor call put

    binding = androidx.databinding.DataBindingUtil.setContentView(this,R.layout.activity_main);

Here- R.layout.activity_main is the name of the file where the view exists

package com.example.implementing_data_binding

import android.os.Bundle
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.snackbar.Snackbar
import androidx.appcompat.app.AppCompatActivity
import android.view.Menu
import android.view.MenuItem
import com.example.implementing_data_binding.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    lateinit var binding: ActivityMainBinding;
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = androidx.databinding.DataBindingUtil.setContentView(this,R.layout.activity_main);
//        setContentView(R.layout.activity_main)
        binding.myId.text = "Yup its done!";
    }

}

Now you are able to access the properties of that view.

try binding.myId.text = "Yup its done!";

Note:- myId is the name of my id we defined in view

Upvotes: 1

SowlM
SowlM

Reputation: 992

There is a couple of things you should do and I try to make it organized and listed: (Based on Android Developers docs from this link and my personal experiences)

  1. You need to use Android Studio 3.6 canary11+ (I'm currently using Android Studio 4 and it is doing the job well for me)

    You can find it from here: https://developer.android.com/studio/archive

  2. You need to upgrade your Gradle wrapper to Gradle "5.6.4" and Gradle build tool to "3.6.0-rc01", higher versions also work so don't be afraid to be updated

    distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
    dependencies {

        ...
        classpath 'com.android.tools.build:gradle:3.6.0-rc01'

    }
  1. To enable view binding in a module, add the viewBinding element to its build.gradle file, as shown in the following example:
    android {
    ...
      viewBinding {
        enabled = true
      }
    }
  1. If you want a layout file to be ignored while generating binding classes, add the tools:viewBindingIgnore="true" attribute to the root view of that layout file:
    <LinearLayout
        ...
        tools:viewBindingIgnore="true" >
        ...
    </LinearLayout>
  1. If view binding is enabled for a module, a binding class is generated for each XML layout file that the module contains. Each binding class contains references to the root view and all views that have an ID. The name of the binding class is generated by converting the name of the XML file to camel case and adding the word "Binding" to the end.

    For example, given a layout file called result_profile.xml:

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

The generated binding class is called ResultProfileBinding. This class has two fields: a TextView called name and a Button called button. The ImageView in the layout has no ID, so there is no reference to it in the binding class.

Every binding class also includes a getRoot() method, providing a direct reference for the root view of the corresponding layout file. In this example, the getRoot() method in the ResultProfileBinding class returns the LinearLayout root view.

  1. To set up an instance of the binding class for use with an activity, fragment or card view adapter perform the following steps:
  • in the activity's onCreate() method:
    private ResultProfileBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ResultProfileBinding.inflate(getLayoutInflater());
    View view = binding.getRoot();
    setContentView(view);
}
  • in the fragments's onCreateView() method:
    private FragmentHousesBinding binding;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        binding = FragmentHousesBinding.inflate(inflater, container, false);

        init();

        return binding.getRoot();
    }
  • in the card view adapter's onCreateViewHolder() method:
    HouseCardPropertyFragmnetBinding binding;

    @Override
    public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        binding = HouseCardPropertyFragmnetBinding.inflate(LayoutInflater
            .from(parent.getContext()), parent, false);

        return new Holder(binding);
    }

    @Override
    public void onBindViewHolder(@NonNull HouseAdapter.Holder holder, int position) {
        holder.bindData(getItem(position));
    }

    class Holder extends RecyclerView.ViewHolder {

        HouseCardPropertyFragmnetBinding view;

        Holder(@NonNull HouseCardPropertyFragmnetBinding v) {
            super(v.getRoot());
            view = v;
        }

        void bindData(Tag item) {
            view.tagTxt.setText(item.Name);

        }
    }

that's it you are free from the findViewById from now on ;)

Upvotes: 79

tushar
tushar

Reputation: 335

ViewBinding is only available from Android Studio 3.6 and above

1:- You need to upgrade your gradle build toold to 3.6.1 in build.gradle (Project level)

 dependencies {
        classpath 'com.android.tools.build:gradle:3.6.1'
             }

2:- You need to enable viewBinding in build.gradle(app)

 android {
viewBinding {
    enabled = true
}}

Once view binding is enabled a binding class is generated for each XML layout. The name of the binding class is generated by converting the name of the XML file to camel case and adding the word "Binding" to the end.

Example:- if a layout file is named as "add_item_activity.xml" then the Name of Binding class will be "AddItemActivityBinding"

3:-To set up an instance of the binding class for use with an activity, create a instance of Binding class, here we will create instance of "AddItemActivityBinding" and will call the static inflate method generated in the binding class

Get a reference to the root view by calling the getRoot() method and pass this root view in setContentView() method

public class AddItemActivity extends AppCompatActivity {
    private AddItemActivityBinding binding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = AddItemActivityBinding.inflate(getLayoutInflater());
        View view = binding.getRoot();
        setContentView(view);

        //now we can access views by their IDs 
        binding.tvTitleMyOrder.setText("Title goes here");

    }

}

Now we can access views by their IDs using instance of binding class

Upvotes: 10

Karthick Ramanathan
Karthick Ramanathan

Reputation: 662

From Android studio 3.6 canary11+ u can use ViewBinding. For reference see this link

Upvotes: 0

Related Questions