Reputation: 563
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
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
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
Reputation: 139
:--------------------------------------This is for Kotlin--------------------------------------:
1) Add viewBinding in your project's Module:
buildFeatures{
viewBinding true
}
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)
Upvotes: 7
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
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
Reputation: 794
View Binding ViewBinding is available from Android Studio 3.6 and above
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.
we can use view binding whenever you inflate layouts such as Fragment, Activity, or RecyclerView Adapter.
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.
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
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
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
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)
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
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'
}
android {
...
viewBinding {
enabled = true
}
}
tools:viewBindingIgnore="true"
attribute to the root view of that layout file: <LinearLayout
...
tools:viewBindingIgnore="true" >
...
</LinearLayout>
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.
private ResultProfileBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ResultProfileBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
}
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();
}
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
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
Reputation: 662
From Android studio 3.6 canary11+ u can use ViewBinding. For reference see this link
Upvotes: 0