文件后面的Android布局引用xml元素
如何引用后面的XML元素 这里有一个特定的用例。假设我有一个带有根LinearLayout的表单,包含多行的LinearLayout,每行有一个或多个文本输入区域 这是我想要的视觉效果。第一张图片来自Venmo的应用程序,第二张是以下XML的呈现 这样的布局可能如下所示:文件后面的Android布局引用xml元素,android,xml,android-layout,android-linearlayout,Android,Xml,Android Layout,Android Linearlayout,如何引用后面的XML元素 这里有一个特定的用例。假设我有一个带有根LinearLayout的表单,包含多行的LinearLayout,每行有一个或多个文本输入区域 这是我想要的视觉效果。第一张图片来自Venmo的应用程序,第二张是以下XML的呈现 这样的布局可能如下所示: <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:o
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/row_card_number"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<EditText
android:id="@+id/card_number"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nextFocusDown="@id/month"/>
</LinearLayout>
<LinearLayout
android:id="@+id/row_date"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<EditText
android:id="@+id/month"
android:layout_height="wrap_content"
android:layout_width="100dp"
android:nextFocusDown="@id/year"/>
<EditText
android:id="@+id/year"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
</LinearLayout>
</LinearLayout>
在这个用例中,为了设置下一个焦点元素,必须进行前向引用。这样,当您按下键盘上的“下一步”按钮时,它将进入正确的视图。在这个示例xml中,如果没有nextFocusDown
s,按next将从一个名称转到另一个月份,而不会转到一年
但是,如果您尝试编译此文件,您将得到一个错误:
错误:(18,36)未找到与给定名称匹配的资源(位于值为“@id/month”的“nextFocusDown”)
这是因为当我试图引用id
month
时,它还没有被初始化,因为这在文件的后面。如何引用文件后面出现的xml中的id?最简单的解决方案就是替换
android:nextFocusDown=“@id/month”
与
android:nextFocusDown=“@+id/month”
当编译器解析XML以将id添加到R.java时,它只是从上到下读取。当您有@id/month
时,它会搜索现有id,但找不到它
但是,如果您执行@+id/month
,它将创建一个新的id,并链接到该id。当它进入实际月份视图中的android:id=@+id/month时,它将它链接到我们已经创建的同一个id
这就提出了一个问题:如果您可以用
@+id/
替换@id/
,并且无论元素的顺序如何,@+id/
都可以工作,为什么还要麻烦使用@id/
原因是如果id不存在,@id/
将抛出编译器错误,@+id/
将在运行时记录警告
考虑以下XML:
<EditText
android:id="@+id/month"
android:layout_height="wrap_content"
android:layout_width="100dp"
android:nextFocusDown="@+id/SOME_RANDOM_ID"/>
<EditText
android:id="@+id/year"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
当解析时,将创建一个新的id元素SOME\u RANDOM\u id
。但是,当Android试图在运行时应用它时,它找不到具有该id的元素。如果您查看Logcat,您将看到以下内容:
W/视图﹕ 找不到id为2131689604的视图
此日志消息很难找到,也很难调试。只要在@+id/
中输入一个小错误,您就会遇到一个难以调试的bug。然而,如果我们做到了:
android:nextFocusDown=“@id/SOME\u RANDOM\u id”
然后我们会得到一个编译器错误,类似于:
错误:(18,36)未找到与给定名称匹配的资源(位于值为“@id/SOME\u RANDOM\u id”的“nextFocusDown”
这更容易查找和调试
tl;dr:您可以使用
@+id/
而不是@id/
,这样您就可以转发引用,但请注意,这会使小的打字错误难以调试
您可能可以使用RelativeLayout使所有视图在xml中以相反的顺序存在,但这对我来说似乎太过分了。我最近也遇到了同样的问题,我在第一次引用元素时使用了@+id/my_new_id,后来在元素定义的xml中使用了,我将@id/my_new_id分配给android:id属性。它似乎工作正常,不必多次使用相同的id写入@+id,以避免可能的警告 例如:
<LinearLayout
...
android:layout_toLeftOf="@+id/my_new_id"
... >
...
</LinearLayout>
<ImageButton
android:id="@id/my_new_id"
... />
...
这是一个自我回答的问题。我真的没有找到任何其他的解释,所以我想我应该自己做。欢迎提出改进建议:)