Android ViewBinding 不会生成 Class 文件

Android ViewBinding Won't Generate Class File

我一直在关注这个 tutorial here 关于如何执行视图绑定的问题,似乎没有什么能正常工作,但首先它似乎没有在修改后生成新的 class 文件模块 gradle 文件,就像它说的那样。

首先,我不确定如何进行 gradle 设置。通过浏览互联网和开发者博客,我发现了三种不同的表达方式:

android {
    ...
    buildFeatures {
        viewBinding = true
    }

或喜欢:

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

或者可能喜欢:

android {
    ...
    viewBinding {
        enabled = true
    }

我已经用所有这些构建(或者说“制作”)了这个项目,但似乎什么也没发生。我知道相关的布局 class 文件,在这种情况下,它只是一组标准的布局和 class 文件,它们是用空 Activity 创建默认项目时附带的,是应该“生成”一个 class 文件,该文件是其关联的 layout 文件的名称,以 Pascal 格式编写,最后加上“Binding”,因此,在这种情况下,布局文件称为 activity_main.xml,因此 class 文件应该是 MainActivityBinding(我知道这是倒退的,但默认情况下他们就是这样的:MainActivity

那么,在那之后,假设 是模块中允许绑定的每个文件的getroot() 方法。但它也不明白。事实上这里提到的大部分代码都不起作用。我到处都是未引用的变量错误,这可能是由于文件没有正确生成,但我真的不知道。

Google 给你的这组说明还有很多问题,但如果这是主要问题,我就从这里开始。

那么我该如何解决这个问题呢?我真的应该做什么?

更新:我发现,通过错误,这就是我应该放在 gradle 文件中的内容(注意:它不接受视图绑定而不是数据绑定)

android {
    ...
    buildFeatures.dataBinding  = true

但是新文件没有生成。我该怎么办?

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>

此外,inb4,这里是 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)
    }
}

您必须在 xml 中使用布局标签才能使用数据绑定和视图绑定,因此您的 xml 代码必须像这样

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

<ConstraintLayout... /> 

</layout>

more information

好吧,经过反复试验,这个对我有用:

1。创建新项目

我将我的命名为“BindTest”

(现在,你可能不必从头开始,但我没有冒险)

2。添加了一个空 Activity

它生成了一个“MainActivity”class 文件和一个“activity_main.xml”布局文件,以及它的布局文件夹

3。编辑模块 Gradle 文件

Android 块的子级,添加:

buildFeatures.dataBinding = true

下面的不行,报错提示我改成上面的(And this is what they suggest on the official documentation site!):

buildFeatures{
        viewBinding{
            enabled=true
        }
    }

4。同步 Gradle 文件

activity_bind.xml中:

  1. layout

    交换androidx.constraintlayout.widget.ConstraintLayout
  2. 从布局中删除以下内容(否则,当您在其中添加另一个布局时,您会收到一条错误消息,指出其中一个重复) :

    • android:layout_width="match_parent"
    • android:layout_height="match_parent"
  3. 删除默认 TextView 并添加线性布局(或其他一些布局)

    (我删除它是因为设计 Window 是我尝试添加线性布局而不删除它的一种方式。如果你能做到,你会更有力量,并且告诉我你的秘密。)

  4. 加入一些 TextView 并给他们 ID

    • 我给了我这些:tv1tv2tv3

5。构建

它应该生成 ActivityBindBinding class (我对我的命名决定感到遗憾),但它确实 NOT 重命名与布局文件关联的class文件;它只是在幕后进行。 实际上看看你所做的是否有效...

6。编辑 BindActivity Class

  1. 添加变量 (Kotlin):private lateinit var binding: ActivityBindBinding
    1. 在重写函数中 onCreate
      • super调用后添加binding = ActivityBindBinding.inflate(layoutInflater)
      • setContentView 中的视图更改为 binding.root

您现在应该可以直接使用 ID (binding.tv1)

7。测试一下

  • onCreate中,最后一行: binding.tv1 = "Hello from inside the class"

当我 运行 完成所有这些后应用程序运行时。

测试数组绑定

不了解你,但 Kotlin 中的数组对我来说很痛苦,所以我测试了它们以确保我做对了。

  1. onCreate中,删除我们制作的最后一行并调用两个方法。它应该是这样的:
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)

         setContentView(binding.root)

        initTextViews() //these two
        setTextViews()  //right chere
    }
  1. 填充 class 中的方法:
    private fun initTextViews() {
        textViews = arrayOf(
            binding.tv1,
            binding.tv2,
            binding.tv3
        )
    }

    private fun setTextViews() {
        textViews.forEachIndexed { ind, tv ->
            tv.text = values[ind].toString()
        }
    }

我再次 运行 应用程序:SUCCESSSSSSSSSSS!!

我想指出的是,当我尝试制作一个没有 Activity 的项目时,它没有正常工作,声称“没有设置默认 Activity” .所以,如果你想避免一些头痛 (因为这就足够了),只需从空 Activity... 开始 [=128] =]