在Android中使用数据绑定时出现错误

33

我正在尝试测试数据绑定,如此处所示的指南。我已经将以下内容包含在我的build.gradle文件(模块app)中:


compileSdkVersion 'android-MNC'
buildToolsVersion '23.0.0 rc2'

在项目 build.gradle 文件中,我已经将以下内容包含在我的依赖项中:

classpath "com.android.tools.build:gradle:1.3.0-beta2"
classpath "com.android.databinding:dataBinder:1.0-rc0"

布局文件与指南中给出的文件完全相同。

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

最初出现了错误元素布局没有所需的属性layout_width和layout_height

我尝试通过分别分配match_parent来修复它。然后我在分配layout_heightlayout_width到线性布局的行上得到了Error parsing XML: duplicate attribute错误。

然后我尝试通过删除这些属性来修复问题。现在每次尝试编译时,都会看到这个错误-error: package my.package.name.databinding不存在。

代码补全在我尝试使用此布局的碎片中完美工作。

那么我错过了什么?


你能否发布你的 user POJO 类和 Activity 类? - N J
请在xml的“type”属性中仔细检查包引用。是my.package.User还是com.example.User - J.G.Sebring
我遇到了这个错误,最终发现是因为我有一个重复的Android XML命名空间。Android Studio中的DataBinding库非常不好,目前无法让您知道问题出在哪里。希望下一个更新会澄清事情。 - Jim Pekarek
您还可以参考此教程 - Chintan Rathod
12个回答

20

您在 XML 文件中的绑定可能无效。

请务必仔细检查:

  1. type 属性是否有效引用数据对象?type="my.package.Class"
  2. 绑定是否有效?name="client" -> "@{client.field}"
  3. 数据字段是否可访问?是否为 public 或封装了 getter 方法
  4. Java 代码和 XML 文件中的字段名称是否匹配?注意检查拼写错误
  5. 如果您已重命名 XML 文件,请确保还更新了绑定对象。OldNameBinding -> NewNameBinding
  6. 清理项目

1
最近我重命名了一个包,尽管清理了项目,但Android Studio仍在寻找'com.oldpackage.app.databinding..'。 重新启动A.Studio解决了问题。 - J.G.Sebring
1
完美的清单,谢谢,对我有用(从网络上复制粘贴后留下了不正确的绑定)。 - Ivan Fazaniuk
1
在3和4之间,我会添加“检查字段/获取器名称和XML中使用的名称之间的拼写错误和不匹配项。”这就是我的情况。在Java文件中,不正确的内容被标记为未使用并显示为灰色。 - WindRider
事后看来很明显,但是为了让BaseObservable/Data类对databinding包可访问,字段/设置器必须是public的。 - Angad
一个XML布局文件中的单个错误,即使所有其他布局文件都没有问题,也会导致在同一个包中使用数据绑定的所有XML布局文件出现相同的错误。 - Hong

17

从我的build.gradle中删除apply plugin: 'com.neenbedankt.android-apt'解决了我的问题。


2
同样的情况,我相信数据绑定已经在内部使用apt了。如果您正在使用dagger或任何其他依赖于apt的库,只需使用提供的“com.google.dagger:dagger-compiler:2.0.1”而不是apt“com.google.dagger:dagger-compiler:2.0.1”。 - frankelot
10
对我而言,问题在于classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4',升级至1.8后问题得到解决。 - miv
1
如果有人在意的话,可以在这里阅读@miv的正确答案:https://bitbucket.org/hvisser/android-apt/issues/38/android-apt-breaks-brand-new-data-binding - tir38
在删除了apt的东西之后,我在butterknife@BindView中得到了NPA异常。 - Kishore Jethava
@sakirk,你能帮我解决这个问题吗:http://stackoverflow.com/q/39837222/6599627 - mahdi pishguy

3

通常情况下,这是由于您的XML布局文件中存在错误,导致无法生成绑定对象。请确保正确编写数据类型,并检查您的大小写。

    <data>
        <variable name="yourObject" type="com.example.simple.YourObject"/>
    </data>

确保对象的正确调用:
    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{yourObject.name}"/>
    <TextView

1
寻找了一段时间后,我找到了这篇帖子。最终我注释掉了大部分的XML文件,然后错误就消失了。从那里开始,我能够调试实际上在我的xml文件中存在(在编译器输出中没有看到)并导致“无法找到数据绑定包”错误的问题。谢谢! - Gene Bo

1

这似乎是在Android Studio中出现的问题。编辑器将其标记为错误,但仍会编译。

我遇到了同样的问题,因此我克隆了这个示例存储库来测试我的系统是否已正确配置以支持数据绑定API https://github.com/mgrzechocinski/android-bindings-example

忽略layout标签上的错误警告。它是错误的。

我注意到的一件事是,如果您只是使用数据绑定通过生成的BindingActivity类访问视图项,则不一定需要data标签。


你不需要 data 标签吗?但是这篇文章说的不一样!https://developer.android.com/tools/data-binding/guide.html - IgorGanapolsky
1
如果您只想利用插件生成的BindingActivity,则不需要数据标记。例如:MainActivityBinding.myview。 - Alec Holmes
@Alec,他确实需要数据标签,因为他显然要在生成的类上使用setUser()方法并自动设置布局中的数据。此外,您可以使用数据标签来设置生成的类名,例如<data name="UserData"></data>,然后生成的类将是UserData而不是LayoutNameBinding。说他不需要数据标签忽略了它的用途以及使用它所获得的好处。 - LukeWaggoner

1
如果您在使用“android-apt”插件来使用Dagger或其他库,并启用数据绑定后,必须删除“android-apt”插件,并在您的依赖项中使用“provided”而不是“apt”。例如,如果您正在使用Dagger,请删除此内容。
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'

和这个

apply plugin: 'com.neenbedankt.android-apt' 

然后替换。
apt 'com.google.dagger:dagger-compiler:2.0'

使用

provided 'com.google.dagger:dagger-compiler:2.0'

0
根据指南的当前版本(2015-11-11),您只需添加两个依赖项: 在项目的build.gradle文件中添加gradle依赖项。目前最新的版本是1.5.0-beta3。
dependencies {
        classpath 'com.android.tools.build:gradle:1.5.0-beta3'
    }

并在模块的 build.gradle 文件中包含 dataBinding 部分:

android{
  ...
  dataBinding {
        enabled = true
    }
  ...
}

错误

错误:包my.package.name.databinding不存在

可能是由于xml和POJO类之间不匹配导致的。


0
您可能在模型和布局文件之间遇到了问题或不匹配。在我的情况下,我有:
...
<TextView
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_toLeftOf="@+id/photo"
            android:layout_toStartOf="@+id/photo"
            tools:text="0912454433"
            android:textStyle="bold"
            android:text="@{contact.cellPhoneNumber}"
            android:layout_below="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

但是我的模型类是这样的:

public class MyContact {
    public String name;
    public String cellphoneNumber; // <-- Notice the lowercase 'p'
}

0

如果您不打算创建getter和setter,必须非常小心地设置POJO类的数据成员为public

如果您有一个没有任何getter或setter的简单POJO

public class User {
   public final String firstName;
   public final String lastName;
   public User(String firstName, String lastName) {
       this.firstName = firstName;
       this.lastName = lastName;
   }
}

如果你创建getter setter,JavaBean风格的类。
public class User {
   private final String firstName;
   private final String lastName;
   public User(String firstName, String lastName) {
       this.firstName = firstName;
       this.lastName = lastName;
   }
   public String getFirstName() {
       return this.firstName;
   }
   public String getLastName() {
       return this.lastName;
   }
}

0
在我的情况下,问题是我将layout_heightlayout_width添加到layout标签和我的根布局中。我刚刚从layout标签中删除了这两个属性并解决了问题。

-1

// 这是在 activity_main.xml 文件中。

  <data>
  <variable
      name="student"
      type="com.example.vishalkamboj.testdatabinding.Student"    />
</data>

// 这是学生类

public class Student {

公共字符串 名字; 公共字符串 姓氏;

public Student(String firstname , String lastname)
{
    this.firstname = firstname;
    this.lastname = lastname;

}

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接