Home > Blockchain >  Android ViewBinding Won't Generate Class File
Android ViewBinding Won't Generate Class File

Time:03-25

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>

more information

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:

  1. Exchange androidx.constraintlayout.widget.ConstraintLayout with simply layout

  2. 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"
  3. 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.)

  4. Throw in some TextViews and give them IDs

    • I gave mine these: tv1, tv2, and tv3

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

  1. Add the variable (Kotlin): private lateinit var binding: ActivityBindBinding
    1. In overridden function onCreate:
      • Add binding = ActivityBindBinding.inflate(layoutInflater) after the super call
      • Change the view in setContentView to be binding.root

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.

  1. 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
    }
  1. 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

  • Related