稍后在文件中安装Android布局参考xml元素

如何引用以后的XML元素?

这是一个特定的用例.假设我有一个带有LinearLayout根的表单,其中包含多行的LinearLayouts,每行包含一个或多个文本输入区域.

这是我想要的视觉效果.第一张照片来自Venmo的应用程序,第二张是以下XML的渲染.

Example of Venmo
The layout

这样的布局可能如下所示:

<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中,没有nextFocusDowns,按next将从name到month,并且永远不会去年.

但是,如果您尝试编译它,您将收到一个错误:

Error:(18, 36) No resource found that matches the given name (at ‘nextFocusDown’ with value ‘@id/month’).

这是因为当我尝试引用它时,id月份尚未初始化,因为这是在文件的后面.如何引用文件中稍后出现的xml中的id?

最佳答案
最简单的解决方案就是更换

机器人:nextFocusDown = “@ ID /月”

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_RANDOM_ID.但是,当Android尝试在运行时应用它时,它无法找到具有该id的元素.如果你看一下Logcat,你会看到:

W/View﹕ couldn’t find view with id 2131689604

此日志消息很难找到并且难以调试. @ id /中的一个小错字,你会有一个非常难以调试的错误.但是,如果我们做了:

机器人:nextFocusDown = “@ ID / SOME_RANDOM_ID”

然后我们会得到编译器错误,例如:

Error:(18, 36) No resource found that matches the given name (at ‘nextFocusDown’ with value ‘@id/SOME_RANDOM_ID’).

这更容易查找和调试.

tl; dr:您可以使用@id /而不是@id /并且您将能够转发引用,但请注意,这可能会使小错误难以调试.

您可以使用RelativeLayout来使所有视图在xml中以相反的顺序存在,但这对我来说似乎有些过分.

转载注明原文:稍后在文件中安装Android布局参考xml元素 - 代码日志