I've been following this tutorial here about how to perform view Binding, and nothing seems to work properly, but first it doesn't seem to generate the new class file after modding the module gradle file, like it says it will.
First, I'm not sure how to do the gradle setup. With my browsing of the internet and developer blogs I've come across three different versions of how to put it:
android {
...
buildFeatures {
viewBinding = true
}
or like:
android {
...
buildFeatures {
viewBinding{
enabled = true
}
}
or maybe like:
android {
...
viewBinding {
enabled = true
}
And I've built (or "made", as it were) the project with all of those and nothing seems to happen. I know that the associated layout class file, which, in this case, is just a standard set of layout and class files that comes with making a default project with an empty Activity, is supposed to "generate" a class file that's the name of its associated layout file, written in Pascal format with "Binding" tacked on the end, thus, in this case, the layout file is called activity_main.xml
, so the class file should therefore be MainActivityBinding
(which, I know is backwards, but that's how they had it by default: MainActivity
)
So then, after that, there's supposed to be a getroot()
method to every file in the module that allows binding. But it don't get that either. In fact most of the code mentioned here doesn't work. I get unreferenced variable errors all over the place, which probably stems from the file not generating properly, but I don't really know.
I've got a lot more problems with this set of directions Google gives you, but if this is the main problem, I'll just start here.
So how do I fix this? What am I really supposed to do?
UPDATE: I figured out, through and error, that this is what I'm supposed to put in the gradle file (note: it would not accept viewbinding instead of databinding)
android {
...
buildFeatures.dataBinding = true
But the new file did not generate. What should I do?
activity_main.xml
:
<?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"
tools:context=".MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Also, inb4, here's MainActivity.kt
:
package com.example.bindtestbinding
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
CodePudding user response:
You must use layout tag in your xml for using databinding and view binding so your xml code code must be like this
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ConstraintLayout... />
</layout>
CodePudding user response:
Alright, so after a lot of trial and error, this is what worked for me:
1. Make New Project
I named mine "BindTest"
(Now, you may not have to start all over, but I took no chances)
2. Added an Empty Activity
It generated a "MainActivity" class file and an "activity_main.xml" layout file, along with its layout folder
3. Edit The Module Gradle File
At the child level of the Android
block, add this:
buildFeatures.dataBinding = true
The following didn't work, and the error suggested I change it to the above (And this is what they suggest on the official documentation site!):
buildFeatures{
viewBinding{
enabled=true
}
}
4. Sync Gradle File
In activity_bind.xml
:
Exchange
androidx.constraintlayout.widget.ConstraintLayout
with simplylayout
Remove the following from the layout (Else, you'll get an error saying there's a duplicate of one of them when you add another layout inside):
android:layout_width="match_parent"
android:layout_height="match_parent"
Remove default
TextView
and add a Linear Layout (or some other layout)(I removed this because the Design Window was being a way when I tried to add a Linear Layout without deleting it. If you can do it, more power to you, and tell me your dark secrets.)
Throw in some
TextView
s and give them IDs- I gave mine these:
tv1
,tv2
, andtv3
- I gave mine these:
5. Build
It should generate ActivityBindBinding
class (I regret my nomenclature decisions), but it does NOT rename the class file associated with the layout file; it merely does it under the covers. To actually see if what you did worked...
6. Edit BindActivity
Class
- Add the variable (Kotlin):
private lateinit var binding: ActivityBindBinding
- In overridden function
onCreate
:- Add
binding = ActivityBindBinding.inflate(layoutInflater)
after thesuper
call - Change the view in
setContentView
to bebinding.root
- Add
- In overridden function
You should now be allowed to use the IDs directly (binding.tv1
)
7. Test It
- In
onCreate
, last line:binding.tv1 = "Hello from inside the class"
When I ran the app after doing all this, it worked.
Test Array Binding
Don't know about you, but arrays in Kotlin are a pain to me, so I tested them to make sure I got this right.
- In
onCreate
, remove the last line we made and call to two methods. It should look like this:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initTextViews() //these two
setTextViews() //right chere
}
- Populate the methods in the class:
private fun initTextViews() {
textViews = arrayOf(
binding.tv1,
binding.tv2,
binding.tv3
)
}
private fun setTextViews() {
textViews.forEachIndexed { ind, tv ->
tv.text = values[ind].toString()
}
}
I ran the app again: SUCCESSSSSSSSSSS!!
I'd like to point out that, when I tried to make a project with No Activity, it didn't work properly, claiming that there was "no Default Activity set". So, if you want to save yourself from some headache (Because this is enough), just start with an Empty Activity...please