双向数据绑定:视图缺少用户定义的类型

Dev*_*-iL 3 data-binding android android-layout 2-way-object-databinding android-view

今天我在Android Studio预览版中发现了最近推出的双向数据绑定功能,并决定尝试一下.

我有一个非常简单的布局(下面的代码),用于撰写和发送消息.我想要实现的是当字段中没有输入文本时,按钮" 禁用 "(以及将来会有相应的图像).

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android">
<data>
    <variable name="msg" type="String"/>
</data>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <EditText
        android:id="@+id/new_message_input"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:paddingStart="10dp"
        android:hint="@string/hint_compose_message"
        android:inputType="textAutoCorrect|textMultiLine"
        android:text="@={msg}"/>
    <ImageButton
        android:id="@+id/btn_send_message"
        android:layout_width="50dp"
        android:layout_height="match_parent"
        android:src="@drawable/ic_send"
        android:enabled="@{!new_message_input.text.isEmpty()}"
        android:clickable="@{!new_message_input.text.isEmpty()}"/>
</LinearLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)

第一个链接中的示例代码显示这样的内容应该足够了:

<layout ...>
  <data>
    <import type="android.view.View"/>
  </data>
  <RelativeLayout ...>
    <CheckBox android:id="@+id/seeAds" .../>
    <ImageView android:visibility="@{seeAds.checked ? View.VISIBLE : View.GONE}" .../>
  </RelativeLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)

但是,当尝试为enabled/ clickable属性实现类似的逻辑时ImageButton,我收到以下错误:

错误:java.lang.RuntimeException:java.lang.RuntimeException:创建数据绑定错误.****/数据绑定错误****消息:标识符必须具有XML文件中的用户定义类型.new_message_input缺少它

问题肯定在于这两行,因为删除它们允许正确创建绑定类.

我的问题是:

  • 我究竟做错了什么?
  • 我该如何解决这个问题?

我也尝试过不同的做法,但结果是一样的:

<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
    <import type="android.widget.EditText"/>
    ...
</data>
<LinearLayout
  ...
  <ImageButton
    ...
    android:enabled="@{!(((EditText)new_message_input).getText().toString().isEmpty())}"
    android:clickable="@{!(((EditText)new_message_input).getText().toString().isEmpty())}"/>
Run Code Online (Sandbox Code Playgroud)

Dev*_*-iL 7

卫生署.

我不记得Data Binding进程将XML ID转换为Binding类中的属性,所有这些都是用较低的camel情况编写的.这意味着为了"@id/new_message_input""@id/btn_send_message"使用数据绑定内部引用,我应该使用生成的名称,在本例中是newMessageInput.

因为它含有这不是从例如立即显现View,其@id已经在驼峰从而自动的工作-因此等同于所产生的名字.

因此解决方案是替换这些线:

    android:enabled="@{!new_message_input.text.isEmpty()}"
    android:clickable="@{!new_message_input.text.isEmpty()}"/>
Run Code Online (Sandbox Code Playgroud)

有:

    android:enabled="@{!newMessageInput.text.isEmpty()}"
    android:clickable="@{!newMessageInput.text.isEmpty()}"/>
Run Code Online (Sandbox Code Playgroud)

或者,如果我这样做,我可以完全解决这个问题:

    android:enabled="@{!msg.isEmpty()}"
    android:clickable="@{!msg.isEmpty()}"/>
Run Code Online (Sandbox Code Playgroud)

在旁注:

如果EditText最初是空的(因此我们希望禁用该按钮),我们应该在布局膨胀时将一个空String对象附加到视图(通过Java;例如StringUtils.EMPTY),以正确地使按钮不可点击.