【问题标题】:Can't get Android two-way data binding to work (IntelliJ IDEA)无法让 Android 双向数据绑定工作(IntelliJ IDEA)
【发布时间】:2016-12-13 14:50:24
【问题描述】:

我遇到了一个问题,我无法让双向数据绑定在 IntelliJ IDEA 中工作。单向绑定工作正常。

这是我的设置:

IntelliJ IDEA Ultimate 2016.2.1

Android API:24

Java:1.8.0_102

分级:2.14.1

这是我的build.gradle 文件:

apply plugin: 'com.android.application'
android {
   compileSdkVersion 24
   buildToolsVersion "24.0.1"

defaultConfig {
    applicationId "com.example.xyz"
    minSdkVersion 17
    targetSdkVersion 24
    versionCode 1
    versionName "1.0"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    debug {
        debuggable true
    }
}
dataBinding {
    enabled = true
}
}

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

这里是layout.xml(单向绑定):

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
<data>
    <variable name="customer"   type="com.example.xyz.model.Customer"/>
</data>
<LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="10dp">
    <TextView android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="@{Integer.toString(customer.age)}"
              tools:text="33"/>
    <EditText
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{customer.name}"/>
</LinearLayout>

这是客户类:

public class Customer extends BaseObservable {
private String name;
private int age;

@Bindable
public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@Bindable
public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}}

这适用于单向数据绑定,但是当我尝试通过将此行更改为以下内容来尝试双向数据绑定时:

android:text="@={customer.name}"

首先,语法无法识别(在 IntelliJ 中变为红色)并出现错误:“Missing /”....编译器错误为:

错误:Gradle:任务 ':app:compileDebugJavaWithJavac' 执行失败。 java.lang.RuntimeException:发现数据绑定错误。 ****/ 数据绑定错误 ****msg:无法在 android.widget.EditText 上找到值为 java.lang.String 的属性 'android:text' 的 getter。 文件:C:\Source\Android\test\app\src\main\res\layout\test_layout.xml 地点:24:33 - 24:43 ****\数据绑定错误****

IntelliJ 还不支持双向数据绑定,还是我缺少什么?

【问题讨论】:

  • 这感觉就像您正在使用旧的数据绑定框架。确保您使用的是最新的 Android Plugin for Gradle -- 在 Android Studio 中,这将在您的顶级 build.gradle 文件中。
  • 我使用的是 IntelliJ IDEA,而不是 Android Studio。 Android SDK 版本、Gradle 版本等在我上面的帖子中。
  • “我使用的是 IntelliJ IDEA,而不是 Android Studio”——我知道。但是,我不使用 IDEA,而且我不知道 Android Plugin for Gradle 版本在 IDEA 项目中的哪个位置。因此,我指出了它在 Android Studio 项目中的位置,作为参考。 “Android SDK 版本、Gradle 版本等在我上面的帖子中”——那些不是the Android Plugin for Gradle。 Gradle 的 Android 插件允许您在问题中显示的 Gradle 脚本中使用 apply plugin: 'com.android.application'
  • 我自己也不确定——我在 Gradle 脚本中根本没有这个条目。我可以设置项目使用哪个Gradle版本,但是我不确定Android Studio Gradle插件版本和IntelliJ Gradle工具版本之间的对应关系是什么。
  • “我不确定Android Studio Gradle插件版本和IntelliJ Gradle工具版本之间的对应关系是什么”——它们是独立但松耦合的,因为不同的插件版本支持的Gradle范围不同版本。

标签: android intellij-idea data-binding


【解决方案1】:

对于属性android:text 数据绑定尝试在EditText 上调用一些getText(),期望返回类型为String。但是由于它返回一个CharSequence,你必须自己定义这个getter。

@InverseBindingAdapter(attribute = "android:text")
public static String captureTextValue(TextView view) {
    return view.getText().toString();
}

【讨论】:

  • 谢谢 - 我是 Android 新手 - 你能解释一下我应该在哪里放置这个适配器,以及如何将它与我现有的代码连接起来吗?我也看过这里,但我仍然不明白整个示例的外观:developer.android.com/reference/android/databinding/…
  • @A.Abrams 这个文档还没有什么大的价值。有一些变化没有反映出来,你也会在那里发现一些明显的错误。最后你可以把这个适配器放在任何地方。我为此使用了一个静态实用程序类。挂钩是自动完成的。
【解决方案2】:

根据这些幻灯片中的信息,我想通了:

http://www.slideshare.net/radekpiekarz/deep-dive-into-android-data-binding

  1. 在项目顶层build.gradle文件中,需要gradle:2.1.0或以上。即使我安装了最新版本,我也将其设置为 gradle:2.0.0。我猜这是@CommonsWare 所指的Android Gradle 插件版本。这是我更正后的顶级build.gradle

    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:2.1.0'
        }
    }
    
    allprojects {
        repositories {
            jcenter()
        }
    }
    
    task clean(type: Delete) {
        delete rootProject.buildDir
    }
    
  2. 修复 gradle 版本后,IntelliJ IDEA 仍然将语法高亮显示为错误,但项目编译正常。但是,双向数据绑定本身仍然不起作用。为了解决这个问题,我在 Customer 类的 name 属性设置器中添加了 notifyPropertyChanged(BR.name)

    public class Customer extends BaseObservable {
        private String name;
        private int age;
    
        @Bindable
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
            notifyPropertyChanged(BR.name);
        }
    
        @Bindable
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
           this.age = age;
        }
    }
    

在此之后,绑定按预期工作 - 我不需要添加任何额外的适配器或更多代码。

【讨论】:

  • 这对我帮助很大。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-23
  • 2016-08-18
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
相关资源
最近更新 更多