Festlegen der ID bei Verwendung von Include in Layout-XML-Datei


117

In meine Layout-XML-Datei habe ich eine andere Layout-XML-Datei aufgenommen (jede mit einer anderen Android-ID).

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

Aber wenn ich es im Emulator ausführe und den Hierarchy Viewer starte, zeigt jedes Layout immer noch 'NO_ID' an, und in meinem Code habe ich findViewById(R.id.test1)undfindViewById(R.id.test2) beide geben null zurück.

Kann mir bitte jemand bei meinem Problem helfen?


6
Ihren IDs fehlt das @Symbol.
AutonomousApps

Antworten:


288

Geben Sie die ID in der an <include>

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

Verwenden Sie dann zwei, findViewByIdum auf Felder im Layout zuzugreifen

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

Mit diesem Ansatz können Sie auf jedes Feld in einem beliebigen Include zugreifen.


18
Diese Methode gibt mir den Nullwert für das test1View-Objekt zurück.
Nirav Shah

4
Ich sehe den Unterschied nicht wirklich, können Sie erklären?
Goddchen

30
Ich habe herausgefunden, dass dies nicht hilft, wenn das von uns eingeschlossene Layout die Zusammenführung verwendet. Wenn jedoch keine Zusammenführung verwendet wird, funktioniert dies.
Zlatko

@Zlatko Yep, und das kann mergeauch theoretisch nicht funktionieren , da das Ergebnis des Einfügens von a mergenicht eine einzelne Ansicht ist, sondern eine Menge von ihnen. Also ist es OK.
Anzeigename

1
Dies funktioniert nur, wenn die Zusammenführung nicht verwendet wird. Im Falle einer Zusammenführung ist dies nicht möglich, wie hier angegeben: code.google.com/p/android/issues/detail?id=36918#c3
Zahid Rasheed

61

Ich habe herausgefunden, dass, wenn Sie ein <merge>Tag in Ihrem Include-Layout verwenden, die ID des Include auf das Merge-Tag übertragen wird, was keine echte Ansicht ist.

Entfernen Sie also entweder die Zusammenführung oder ersetzen Sie sie durch ein Layout.

Tor Norbye schrieb :

Das <include>Tag ist keine echte Ansicht, daher wird findByView es nicht finden. Das Attribut @id (und alle anderen Attribute, die Sie für das Include-Tag festgelegt haben) wird stattdessen auf das Root-Tag des Include-Layouts angewendet. Ihre activity.getView (R.id.included1) sollte also tatsächlich die <TextView>selbst sein.


3
Gut. Ich entferne das Zusammenführungs-Tag und es funktioniert, aber meine Frage hier ist, wie das Zusammenführungs-Tag verwendet wird, wenn ein Include-Layout ohne es funktioniert.
Ankur Chaudhary

35

Romain Guy gibt an, dass Sie die ID eines enthaltenen Layouts überschreiben können, indem Sie ein android:idAttribut in das <include>Tag einfügen.

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

1
Das ist richtig. Der Verweis auf das Stammelement in der enthaltenen Layoutdatei erfolgt über die im Tag 'include' angegebene ID (sofern diese nicht angegeben ist).
Tom R

1
ID in <include> =
Roots

Wenn ich zuerst die ID setze (im Include-Tag überschreibt sie die ID aus dem enthaltenen Layout, oder?), Wird das Include-Tag zunächst als '@ + id / cell1' und dann als layout = 'angezeigt. @ layout / workspace_screen 'überschreibt die android: id erneut mit der ID des enthaltenen Layouts. @ Ron Romeros Antworten sind für mich sinnvoller.
Neon Warge

13

Ich denke, die Top-Antwort verfehlt den wichtigsten Punkt und könnte die Leute dazu verleiten, das zu denken <include/> Tag eine Ansicht erstellt, die den Include-Inhalt enthält.

Der entscheidende Punkt ist , dass die umfassen id ist vergangen an die Stammansicht der Includes Layout - Datei.

Das bedeutet, dass dies:

// 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"
    />

Wird dies:

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

4

Ja ist so, aber vorsichtig, wenn das in das Include-Feld eingefügte Layout ein benutzerdefiniertes ist und Sie auf dieses Root-Layout zugreifen möchten. Dieses Layout in diesem Fall @ layout / test test wird tatsächlich in der ersten Zeile zurückgegeben.

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


2

Das Problem ist, dass wir versuchen, eine ID zu verwenden, die in der aktuellen Layoutdatei nicht deklariert ist. Anstatt erneut zu deklarieren, kann id einfach mit referenziert werden @+id/. Wenn Sie den ursprünglichen ID-Namen über Android Studio umgestalten, wird er auch im enthaltenen Layout umgestaltet.

<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

Wenn Sie <RecyclerView>find verwenden, finden Sie die ID <include>von mithilfe einer Instanz der aufgeblasenen Ansicht, oder es wird null zurückgegeben .

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

Wenn Sie die ID entweder auf das Root-Tag des enthaltenen Layouts festgelegt haben, können Sie diese ID verwenden oder die ID auf das enthaltene Layout festlegen.

Sie können die ID jedoch nicht auf beide setzen, da dies eine Ausnahme auslösen kann.

<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>

Oder

<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

Wenn Sie über Include sprechen, haben Sie entweder eine ID in der Stammansicht in der enthaltenen Layoutdatei oder in der Include-Zeile selbst und nicht in beiden. Beispielsweise:

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

Layout 1 Datei

<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>

Das obige Beispiel ist falsch, da technisch gesehen zwei IDs für dasselbe Layout deklariert sind. Sie müssen also auswählen, welches Element die ID haben soll.


0

Wow, ich kann nicht glauben, dass diese Frage noch nicht die richtige Antwort hat. Es ist einfach Tags saugen. Sie können nur die Dinge ändern , die mit beginnen , android:layout_was android:idnicht übereinstimmt. Die Antwort ist also, dass Sie nicht können. Es tut uns leid. Stattdessen können Sie eine Klasse erstellen, die eine ViewGroup ist, die die darin enthaltenen Ansichten aufbläst, und diese dann als Tag in Ihr Layout einfügen, aber das war es auch schon.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.