android: data binding error: cannot find symbol class

android: data binding error: cannot find symbol class

我开始使用 DataBinding 功能。我遇到了问题。

Error:(21, 9) error: cannot find symbol class ContactListActivityBinding

build.gradle(模块:app)

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "com.letsnurture.ln_202.databindingdemo"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    dataBinding {
        enabled = true
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
}

ContactListActivity.java

import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;

import com.letsnurture.ln_202.databindingdemo.model.Contact;

public class ContactListActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ContactListActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_contact_list);
        Contact user = new Contact("Chintan Soni", "+91 9876543210");
        binding.setContact(user);

//        setContentView(R.layout.activity_contact_list);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_contact_list, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

content_contact_list.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="com.letsnurture.ln_202.databindingdemo.ContactListActivity"
    tools:showIn="@layout/activity_contact_list">

    <data>

        <variable
            name="user"
            type="com.letsnurture.ln_202.databindingdemo.model.Contact" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="@dimen/activity_horizontal_margin"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.contactName}"
            tools:text="Name" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.contactNumber}"
            tools:text="Number" />
    </LinearLayout>
</layout>

activity_contact_list.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true"
    tools:context="com.letsnurture.ln_202.databindingdemo.ContactListActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_contact_list" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>

您需要在 activity 布局中声明并传递绑定,而不是在包含的布局中。

示例来自 the documentation

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bind="http://schemas.android.com/apk/res-auto">
   <data>
       <variable name="user" type="com.example.User"/>
   </data>
   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <include layout="@layout/name"
           bind:user="@{user}"/>
       <include layout="@layout/contact"
           bind:user="@{user}"/>
  </LinearLayout>
</layout>

Here, there must be a user variable in both the name.xml and contact.xml layout files.

您必须更改要绑定的 activity_contact_list - 像在 content_contact_list 中那样添加布局标签。不要忘记,activity_contact_list 中的根布局必须有一个要生成的 Binding class 的 id,并将被命名为 ActivityContactListBinding(即使用驼峰式而非下划线的布局)。

接下来,在 activity_contact_list 中,给 <include layout="@layout/content_contact_list" /> 一个 ID,然后您将可以通过 ActivityContactListBinding 实例访问其绑定实例。

类似的东西:

binding.contentContactList.setContact(user);

如果有效请告诉我。

我一直运行解决这个问题。我认为这与 android studio 不了解动态生成的文件有关。如果您拥有数据绑定的所有其他权利,请尝试文件 > 使 Caches/Restart... 无效和 select 使缓存无效并重新启动。然后尝试导入 BR 文件...应该可以正常导入。

您可能需要进行清理和重建。

这是您的代码

ContactListActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_contact_list);

替换此代码

ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_contact_list);

请参考android developer guide

Layout file was main_activity.xml so the generate class was MainActivityBinding

因为你的 xml 被命名为 "activity_contact_list.xml",你应该使用 A​​ctivityContactListBinding 而不是原来的

我陷入这个问题是因为我的Activity被称为MainActivityMVVM并且Binding被转换成MainActivityMvvmBinding而不是MainActivityMVVMBinding。在深入研究生成的 类 后,我发现了问题。

确保您的模型名称和参考名称相同:

例如name="item"必须匹配android:checked="@={item.checked }"

<data>
    <variable
        name="item"
        type="com.simone.mywordlist.model.MyModel" />
</data>

            <Switch
                android:id="@+id/my_switch"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="@={item.checked}"
            />

我遇到了同样的错误,但使用了 Kotlin。

为了解决它,我对 gradles 文件做了一些更改:

项目的Gradle文件中:

dependencies {
    classpath "com.android.tools.build:gradle:3.1.2"
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.40"
}

app 的 Gradle 文件中:

dependencies {

    ...
    implementation "android.arch.lifecycle:extensions:1.1.1"
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.30"
    kapt 'com.android.databinding:compiler:3.1.2'
}


kapt {
    generateStubs = true
}

//used to resolve annotation conflicts
configurations.all {
    resolutionStrategy {
        force 'com.android.support:support-annotations:23.1.1'
    }
}

关键点

您的布局名称在 snake_case.

activity_login.xml

那么您的绑定 class 名称将采用 CamelCase.

ActivityLoginBinding.java

同样在创建布局后构建项目。有时不会自动生成。

您可以查看 以获得有关数据绑定错误和解决方案的完整信息。我将在下面尝试讲述一些要点。

我用来解决绑定问题的 5 个技巧。

假设您有 enabled data binding in build.gradle and you have converted your layout to binding layout.

首先绑定 class 当您将布局转换为绑定布局时自动生成。当后台线程不工作时,有时它不会生成。这里有一些提示可以帮助您解决此问题。

(1) Name of generated class

布局名称在 snake_case activity_main.xml

数据绑定 class 将采用 PascalCase,如 ActivityMainBinding.

(2). Type full name of Binding class

有时我觉得当你输入 ActivityMai... 时,它 不显示建议 ,但是 并不意味着 class 是 未生成的 。在这种情况下,您应该 键入预期生成的 class 的全名 。就像键入 ActivityMainBinding 一样,它 将显示导入弹出窗口 。 (这就是我多次遇到的问题。)

仍然没有得到导入建议。尝试手动导入。

import <yourpackage>databinding.ActivityMainBinding;

(3). Rebuild Project

如果还没有生成你的class。 (有时我们粘贴布局文件时会发生这种情况)。然后 Build> Rebuild 重建项目不是构建或制作项目)。它将生成您的数据绑定 class。 (Rebuild 总是对我有魔力。

(4) 如果您在布局中创建了 <variable 而它 没有在数据绑定 class 中显示其 setter 和 getter,然后 按照第 4 个点 .

(5) 如果您的 class 没有生成,那么您应该 检查构建是否因错误而失败 在你的布局文件中。数据绑定 class 将在成功构建时生成。

这就是我为解决数据绑定错误所做的全部工作。如果您有任何进一步的问题,您可以在这里发表评论。

在我的例子中,在生成的数据绑定中有一个与丢失的导入同名的包 class.. 编译器似乎被混淆了。

有时这些错误的原因不是 DataBinding 本身,而是我们代码的其他部分。在我的例子中,我在 Room 数据库中有一个错误,因此编译器无法生成绑定 类,它给了我这些错误。

根据Google:

Previous versions of the data binding compiler generated the binding classes in the same step that compiles your managed code. If your managed code fails to compile, you might get multiple errors reporting that the binding classes aren't found. The new data binding compiler prevents these errors by generating the binding classes before the managed compiler builds your app.

因此,要启用新的数据绑定编译器,请将以下选项添加到您的 gradle.properties 文件中:

android.databinding.enableV2=true

您还可以通过添加以下参数在 gradle 命令中启用新编译器:

-Pandroid.databinding.enableV2=true

注意 Android Studio 版本 3.2 中的新编译器默认 启用.

包名不当也会导致上述错误。从 Android Gradle 插件 3.2 开始(据我所知)CamelCase 包名称将被错误地推断为 classes,这将破坏生成的绑定对象。

示例:

src
|
-> FooPackage
    |
    -> Bar.java

会被错误生成为

import src.FooPackage

...

public abstract class MyBinding extends ViewDataBinding {
    @NonNull
    public final FooPackage.Bar mInstance;
...
}

这显然没有任何意义。

根据java conventions重构FooPackagefoopackage并保存。然后你会得到:

import src.foopackage.Bar

...

public abstract class MyBinding extends ViewDataBinding {
    @NonNull
    public final Bar mInstance;
...
}

只需删除项目目录中的 "build" 文件夹并重新编译,我希望它对你也有用

您需要将标签添加到 Activity 的 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">
    <data>
        <variable
             name=""
             type="" />
    </data
    <android.support.design.widget.CoordinatorLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
  tools:context="com.letsnurture.ln_202.databindingdemo.ContactListActivity">

    </android.support.design.widget.CoordinatorLayout>
</layout>

然后,将 android:id 添加到您的标签中

之后,您将拥有一个 ActivityContactListBinding 对象,您可以在包含的布局上访问和绑定变量。

布局文件有问题时可能会出现此问题。 就我而言,我只是使用了错误的方式来调用方法

android:onClick="@={() -> viewModel.showText()}"

而不是

  android:onClick="@{() -> viewModel.showText()}"

就我而言,我遇到了同样的问题,但原因不同。我的 onClick 函数在 activity class 中被声明为私有].

// this will not be visible in the binded layout because it's private!
private fun mainButtonClick(view: View) {
    if (viewModel.isRecording.value == true) {
        stopRecordingAndPlaying()
    } else {
        startRecordingAndPlaying()
    }
}

不要忘记在应用级别添加 gradle、apply plugin: 'kotlin-kapt'

您的模型在 androidX 中只有 getter 和 setter 否则在视图中找不到您的模型并显示此错误

public class User {

String name;

public String getName() {
    return name;
}
public User(String name) {
    this.name = name;
}

}

我遇到了同样的问题,我发现缺少变量名和方法。仔细检查布局文件或查找显示 DATABINDINGISSUE 的构建错误,或使之无效并重新启动 android studio。它应该有效。

在我的项目中,问题在于:

android:text="@{safeUnbox(viewmodel.population)}"

所以我把它包装在 String.valueOf() :

android:text="@{String.valueOf(safeUnbox(viewmodel.population))}"

已解决

我在调用我的 onClick 错误,导致了这个错误。所以我改变了

android:onClick="@{listener.onDogClicked()}"

android:onClick="@{listener::onDogClicked}"

对我来说,这是布局 xml 绑定中的一个错误,我有

app:setNameString="@{person}"

而不是

app:nameString="@{person}"

类型名称必须与您在@BindingAdapter 中设置的名称相匹配class(如果您使用的是绑定适配器)

确保其他答案中描述的命名约定正确,并尝试使缓存无效并重新启动,删除 temp/cache 文件夹后问题仍然存在。

我把它去掉如下: 添加一个新的虚拟 XML 资源。这将在整个项目中触发绑定及其 meta-data 到 re-create。烦人的编译错误应该不再可见了。您现在删除添加的虚拟 XML。

对我来说,截至 2020 年 8 月,绑定会反复自动损坏。它似乎咬得比它在引擎盖下咀嚼的还要多。

实际上,由于各种原因可能会发生这种情况,并且由于数据绑定中的日志记录机制不佳,很难找到 reason.So 找到正确的错误首先转到终端 运行以下命令-

gradlew :app:build --stacktrace

它将向您显示正确的错误以及 XML 中发现错误的行数。

例如-

ERROR: Could not find accessor com.example.model file://app\src\main\res\layout\fragment_example.xml Line:91

您的问题实际上可能出在这一行:

<include layout="@layout/content_contact_list" />

Android Studio 有时会有点困惑,将 include layout 用作 layout 标签。更令人沮丧的是,这可能是第一次工作,但稍后无法对 Java/Kotlin 代码进行修改,然后在强制重建绑定的调整后再次工作。您可能想用动态填充的内容替换 <include> 标签。

将您在项目中用于绑定的所有包名称设为小写。

您需要检查您的布局文件,此错误是由于数据绑定表达式的错误使用造成的,即您可能没有使用正确的语法

我遇到过同样的问题 当我在没有 viewBinding

的情况下尝试这个
  buildFeatures {
        dataBinding true
    }

这将在使视图绑定一切正常工作时出现该错误

  buildFeatures {
        dataBinding true
        viewBinding true
    }

如果您更改了对象包位置并且忘记将其导入信息更新到 xml,则可能会发生该错误。请检查您的对象包位置及其 xml 导入包位置。

在我的例子中,我将 onClick 函数用于调用异步/suspend 函数,这给了我一个错误 cannot find a symbol class ... impl.

.xml 文件

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

    <data>
        <variable
            name="dataFragment"
            type="com.example.todoapp.fragment.SubmissionFragment" />
    </data>
    
    <Button
        android:id="@+id/keepBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:onClick="@{() -> dataFragment.submit()}"
        android:text="Add" />
</layout>

.片段文件

private lateinit val stringList: List<String>

...

suspend fun submit() {
        dataDao.insert(stringList)
        val action = SubmissionFragmentDirections.actionSubmissionFragmentToTodoFragment()
        findNavController().navigate(action)
    }

然后我通过删除挂起函数将 Async Method 替换为 Launch Method 并插入 viewModelScope.launch

fun submit() {
    viewModelScope.launch {
       dataDao.insert(stringList)
    }

    val action = SubmissionFragmentDirections.actionSubmissionFragmentToTodoFragment()
    findNavController().navigate(action)
    }

参考:https://www.geeksforgeeks.org/launch-vs-async-in-kotlin-coroutines/