双向数据绑定:视图缺少用户定义的类型
Two-Way Data Binding: View is missing user defined type
今天我在 Android Studio 预览中发现了最近引入的 two-way data binding 功能,并决定试一试。
我有一个非常简单的布局(下面的代码),用于撰写和发送消息。我试图实现的是在字段中没有输入文本时使用按钮“disabled”(并且在未来,相应地有一些不同的图像)。
<?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>
第一个 link 中的示例代码显示像这样的东西应该足够了:
<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>
但是,当尝试为 ImageButton
的 enabled
/clickable
属性实现类似逻辑时,出现以下错误:
Error:java.lang.RuntimeException
: java.lang.RuntimeException
: Found data binding errors.
****/ data binding error ****msg:Identifiers must have user defined types from the XML file. new_message_input
is missing it
问题肯定出在这两行上,因为删除它们可以正确创建绑定 class。
我的问题是:
- 我做错了什么?
- 我该如何解决?
我也尝试了一些不同的做法,但结果是一样的:
<?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())}"/>
多哈
我忘记了数据绑定过程将 XML ID 转换为绑定 class 中的属性,所有这些都是用 小驼峰式 [=43] 编写的=].这意味着为了使用数据绑定从 "@id/btn_send_message"
中引用 "@id/new_message_input"
,我应该使用 生成的名称 ,在本例中是 newMessageInput
.
这在示例中不是很明显,因为它包含一个 View
,其 @id
已经在 camelCase 中,因此与生成的名称相同- 因此自动工作。
因此,解决方案是替换这些行:
android:enabled="@{!new_message_input.text.isEmpty()}"
android:clickable="@{!new_message_input.text.isEmpty()}"/>
与:
android:enabled="@{!newMessageInput.text.isEmpty()}"
android:clickable="@{!newMessageInput.text.isEmpty()}"/>
或者我可以完全解决这个问题:
android:enabled="@{!msg.isEmpty()}"
android:clickable="@{!msg.isEmpty()}"/>
旁注:
如果 EditText
最初是空的(因此我们希望按钮被禁用),我们应该将一个空的 String
对象附加到视图(通过 Java;例如 StringUtils.EMPTY
),在布局时 inflation,正确地使按钮不可点击。
今天我在 Android Studio 预览中发现了最近引入的 two-way data binding 功能,并决定试一试。
我有一个非常简单的布局(下面的代码),用于撰写和发送消息。我试图实现的是在字段中没有输入文本时使用按钮“disabled”(并且在未来,相应地有一些不同的图像)。
<?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>
第一个 link 中的示例代码显示像这样的东西应该足够了:
<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>
但是,当尝试为 ImageButton
的 enabled
/clickable
属性实现类似逻辑时,出现以下错误:
Error:
java.lang.RuntimeException
:java.lang.RuntimeException
: Found data binding errors. ****/ data binding error ****msg:Identifiers must have user defined types from the XML file.new_message_input
is missing it
问题肯定出在这两行上,因为删除它们可以正确创建绑定 class。
我的问题是:
- 我做错了什么?
- 我该如何解决?
我也尝试了一些不同的做法,但结果是一样的:
<?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())}"/>
多哈
我忘记了数据绑定过程将 XML ID 转换为绑定 class 中的属性,所有这些都是用 小驼峰式 [=43] 编写的=].这意味着为了使用数据绑定从 "@id/btn_send_message"
中引用 "@id/new_message_input"
,我应该使用 生成的名称 ,在本例中是 newMessageInput
.
这在示例中不是很明显,因为它包含一个 View
,其 @id
已经在 camelCase 中,因此与生成的名称相同- 因此自动工作。
因此,解决方案是替换这些行:
android:enabled="@{!new_message_input.text.isEmpty()}"
android:clickable="@{!new_message_input.text.isEmpty()}"/>
与:
android:enabled="@{!newMessageInput.text.isEmpty()}"
android:clickable="@{!newMessageInput.text.isEmpty()}"/>
或者我可以完全解决这个问题:
android:enabled="@{!msg.isEmpty()}"
android:clickable="@{!msg.isEmpty()}"/>
旁注:
如果 EditText
最初是空的(因此我们希望按钮被禁用),我们应该将一个空的 String
对象附加到视图(通过 Java;例如 StringUtils.EMPTY
),在布局时 inflation,正确地使按钮不可点击。