在布局XML文件中使用包含时如何指定ID


117

在我的布局xml文件中,我包括了其他布局xml文件(每个文件都有不同的android id)。

<include layout="@layout/view_contact_name" android:id="+id/test1"/>
<include layout="@layout/view_contact_name" android:id="+id/test2"/>

但是,当我在模拟器中运行它并启动Hierarchy Viewer时,每个布局仍然显示“ NO_ID”,并且在我的代码中,我拥有 findViewById(R.id.test1)并且findViewById(R.id.test2)都返回null。

谁能帮我解决我的问题?


6
您的ID缺少@符号。
AutonomousApps

Answers:


288

在中指定ID <include>

<include layout="@layout/test" android:id="@+id/test1" />

然后使用两个findViewById来访问布局中的字段

View test1View = findViewById(R.id.test1);
TextView test1TextView = (TextView) test1View.findViewById(R.id.text);

使用这种方法,您可以访问任何包含中的任何字段。


18
此方法为test1View对象返回空值。
尼拉夫·沙

4
我看不出有什么区别,您能解释一下吗?
Goddchen 2013年

30
我发现,如果我们包含的布局正在使用合并,这将无济于事。但是在不使用合并的情况下,此方法可行。
Zlatko

@Zlatko是的,merge即使在理论上也无法使用,因为包含a的结果merge不是单个视图,而是一堆视图。这样就可以了
显示名称

1
这仅在不使用合并的情况下有效。如果合并,则无法按此处指定的方式进行操作:code.google.com/p/android/issues/detail?id=36918#c3
Zahid Rasheed

61

我发现,如果您<merge>在包含布局中使用标签,则包含ID会转移到不是真实视图的合并标签中。

因此,要么删除合并,要么用某种布局替换它。

Tor Norbye 写道

<include>标记不是真实视图,因此findByView将找不到它。@id属性(以及您在include标记上设置的任何其他属性)将改为应用于包含布局的根标记。因此,您的activity.getView(R.id.included1)实际上应该就是<TextView>它自己。


3
好一个 我删除了合并标记,它开始起作用,但是我的问题是,如果有任何包含布局但没有合并标记,合并标记的用途是什么?
Ankur Chaudhary

35

罗曼·盖伊(Romain Guy)表示,您可以通过android:id<include>标签内放置属性来覆盖包含的版式的ID 。

<include android:id="@+id/cell1" layout="@layout/workspace_screen" />

1
这是对的。在包含的布局文件中引用根元素的方法是通过'include'标记中给出的ID(除非未给出)。
Tom R

1
<include>中的ID =包含布局中根的ID
Fadils

在我看来,如果我先设置ID(在include标签中,它会覆盖包含的布局中的ID,对吗?),我的include标签最初将是'@ + id / cell1',然后是layout =' @ layout / workspace_screen'将再次使用所包含布局的ID覆盖android:id。@Ron Romero的回答对我来说更有意义。
霓虹灯Warge

13

我认为最重要的答案错过了最重要的一点,并可能误导人们以为<include/>标签创建了包含包含内容的View。

关键是include的id传递了到的根视图包含的布局文件。

这意味着:

// activity_main.xml
<include layout="@layout/somelayout" android:id="@+id/someid"/>

// somelayout.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />

变成这个:

// activity_main.xml
<ImageView
    android:id="@+id/someid"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />

4

yes就是这样,但是当在include字段中插入的布局是自定义布局并且您要访问该根布局时要小心。在这种情况下,该布局@ layout / test测试实际上是在第一行中返回的。

test test1View = (test)findViewById(R.id.test1);


2

问题是我们尝试使用当前布局文件中未声明的ID。无需再次声明,只需使用即可引用id @+id/。如果您通过Android Studio重构原始ID名称,它也会在包含的布局中重构。

<include layout="@layout/toolbar"/>

<TextView
    android:id="@+id/txt_description"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    **android:layout_below="@+id/toolbar"**
    android:layout_marginTop="16dp"
    android:paddingLeft="8dp"
    android:paddingRight="8dp"/>

2

在使用<RecyclerView>find的ID的情况下,使用<include>膨胀视图的实例,否则它将返回null

public class ViewHolder extends RecyclerView.ViewHolder {

        private mTextView;

        public ViewHolder(View view) {
            super(view);
            View include_1 = view.findViewById(R.id.include_1);
            mTextView = (TextView) include_1.findViewById(R.id.text_id);
        }
    }

1

如果已将id设置为包含布局的根标签,则可以使用该ID或将id设置为包含布局。

但是您不能同时将id设置为它可能会引发异常。

<include layout="@layout/view_contact_name" android:id="+id/test1"/>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

....
</LinearLayout>

要么

<include layout="@layout/view_contact_name"/>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        android:id="@+id/llBottomMainView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

....
</LinearLayout>

0

在谈论包含时,您要么在包含的布局文件内的根视图上,要么在包含行本身上具有一个ID,而不是两者都具有。例如:

<include layout="@layout/layout1" android:id="@+id/layout1"/>

版面1档案

<RelativeLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/layout2">

</RelativeLayout>

上面的示例是错误的,因为从技术上讲,您为同一布局声明了两个id。因此,您需要选择哪个元素具有ID。


0

哇,我不敢相信这个问题还没有正确的答案。简单的标签很烂。您只可以改变的事情,与启动android:layout_android:id不匹配。所以答案是你做不到。抱歉。相反,您可以做的是创建一个将成为ViewGroup的类,该类将使内部包含的视图膨胀,然后将其作为标记添加到布局中,仅此而已。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.