android:数据绑定错误:找不到符号类

时间:2016-02-01 09:13:39

标签: android android-databinding

我开始使用DataBinding功能。我面临着问题。

  

错误:(21,9)错误:找不到符号类   ContactListActivityBinding

build.gradle(模块:应用)

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>

29 个答案:

答案 0 :(得分:15)

我一直遇到这个问题。我相信它与android studio没有意识到动态生成的文件有关。如果你有其他正确的数据绑定尝试文件&gt;使高速缓存/重新启动无效...并选择“使高速缓存无效并重新启动”。然后尝试导入BR文件...它应该导入正常。

您可能需要投入清洁和重建。

答案 1 :(得分:9)

这是你的代码

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

替换此代码

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

答案 2 :(得分:8)

请参阅android developer guide

  

布局文件是main_activity.xml,因此生成类是MainActivityBinding

由于您的xml名为“activity_contact_list.xml”,因此您应该使用 ActivityContactListBinding 而不是原来的

答案 3 :(得分:6)

有关数据绑定错误和解决方案的完整信息,请参见 Main Answer 。我将在下面尝试说明一些要点。

我用来解决绑定问题的5条提示。

假定您在build.gradle中具有 enabled data binding ,并且已将布局转换为 binding layout

首先,将布局转换为绑定布局时,会自动生成绑定类。仍然有时在后台线程不工作时不会生成它。这是一些解决问题的技巧。

  

(1)生成的类的名称

布局名称采用 snake_case activity_main.xml

数据绑定类将位于 CamelCase 中,如ActivityMainBinding

  

(2)。输入绑定类的全名

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

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

import <yourpackage>databinding.ActivityMainBinding;
  

(3)。重建项目

如果仍然没有生成您的类。 (有时,我们粘贴布局文件会发生这种情况)。然后从Build> Rebuild 重建项目不构建或制作项目)。它将生成您的数据绑定类。 (重建一直为我做魔术。

(4)如果您在布局中创建了 <variable ,但它未显示其设置者和获取者在数据绑定类中,然后遵循第4点

(5)即使您的班级未生成,您仍应检查布局文件中的构建是否因错误而失败。数据绑定类将成功生成。

这就是我为解决我的数据绑定错误所做的一切。如果您还有其他问题,可以在这里发表评论。

Source answer

答案 4 :(得分:4)

我说我的onClick错误,导致此错误。所以我改变了

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

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

答案 5 :(得分:3)

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

来自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>
  

这里,name.xml和contact.xml布局文件中都必须有一个用户变量。

答案 6 :(得分:3)

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

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

代替

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

答案 7 :(得分:2)

您必须更改要绑定的activity_contact_list - 添加布局标记,就像在content_contact_list中一样。不要忘记,activity_contact_list中的根布局必须具有要生成的Binding类的id,并且将命名为 ActivityContactListBinding (即使用camel cast而不是下划线的布局名称)。

接下来,在activity_contact_list内,给<include layout="@layout/content_contact_list" />一个id,然后你可以通过ActivityContactListBinding实例访问它的绑定实例。

像:

binding.contentContactList.setContact(user);

让我知道它是否有效。

答案 8 :(得分:2)

在我的项目中,这很麻烦:

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

因此,我将其包装在String.valueOf()中:

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

解决了

答案 9 :(得分:2)

我遇到了同样的问题,我发现缺少变量名和方法。仔细检查布局文件或查找显示DATABINDINGISSUE的生成错误,或使Android Studio无效并重新启动。应该可以。

答案 10 :(得分:2)

实际上可能由于各种原因而发生,并且由于数据绑定中的日志记录机制不佳,很难找到原因。因此首先要获得正确的错误,然后转到终端并运行以下命令-

gradlew :app:build --stacktrace

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

例如-

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

答案 11 :(得分:2)

我遇到了同样的错误,但使用了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'
    }
}

答案 12 :(得分:1)

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

根据 Google

  

以前的数据绑定编译器版本在编译托管代码的同一步骤中生成了绑定类。如果托管代码无法编译,则可能会报告多个错误,提示未找到绑定类。新的数据绑定编译器通过在托管编译器构建应用之前生成绑定类来防止这些错误。

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

android.databinding.enableV2=true

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

-Pandroid.databinding.enableV2=true

注意,默认情况下启用了Android Studio版本 3.2 中的新编译器

答案 13 :(得分:1)

不正确的程序包名称也可能导致上述错误。从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 conventionsFooPackage重构为foopackage并保存。然后您将获得:

import src.foopackage.Bar

...

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

答案 14 :(得分:1)

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

答案 15 :(得分:1)

关键点

您的布局名称使用 snake_case

activity_login.xml

然后您的绑定类名称将在 CamelCase 中。

ActivityLoginBinding.java

也在创建布局后构建项目。有时它不是自动生成的。

答案 16 :(得分:1)

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

我摆脱了它如下: 添加一个新的虚拟XML资源。这将触发绑定及其元数据以在整个项目中重新创建。烦人的编译错误应该不再可见。现在,您删除添加的虚拟XML。

对于我而言,截至2020年8月,绑定将自动反复遭到破坏。它看起来比它在引擎盖下的咀嚼要多得多。

答案 17 :(得分:1)

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

例如,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}"
            />

答案 18 :(得分:0)

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

答案 19 :(得分:0)

您的问题可能实际上在此行上:

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

Android Studio有时会有些混乱,并以include layout作为layout标签。更令人沮丧的是,这可能第一次起作用,以后无法在Java / Kotlin代码上进行修改,然后在经过强制使其重新构建绑定的调整后再次起作用。您可能想用动态填充的标签替换<include>标签。

答案 20 :(得分:0)

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

app:setNameString =“ @ {person}”

代替

app:nameString =“ @ {person}”

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

答案 21 :(得分:0)

我遇到了同样的问题 当我在没有 viewBinding 的情况下尝试此操作时

  buildFeatures {
        dataBinding true
    }

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

  buildFeatures {
        dataBinding true
        viewBinding true
    }

答案 22 :(得分:0)

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

public class User {

String name;

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

}

答案 23 :(得分:0)

别忘了添加应用级gradle apply plugin: 'kotlin-kapt'

答案 24 :(得分:0)

就我而言,我有相同的问题,但原因有所不同。我的onClick函数在活动类中被声明为私有,因此请确保,如果您在布局内使用处理程序函数,则该函数一定不能为私有

// 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()
    }
}

答案 25 :(得分:0)

您需要将代码添加到“活动”的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对象,并且可以在包含的布局上访问和绑定变量。

答案 26 :(得分:0)

只需删除您项目目录中的“ build”文件夹,然后再次编译,我希望它也对您有用

答案 27 :(得分:0)

就我而言,在生成的数据绑定类中有一个与丢失的导入同名的软件包。似乎编译器感到困惑。

答案 28 :(得分:0)

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