Come specificare l'ID quando gli usi includono nel file xml di layout


117

Nel mio file xml di layout, ho incluso altri file xml di layout (ciascuno con un ID Android diverso).

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

Ma quando lo eseguo nell'emulatore e avvio Hierarchy Viewer, ogni layout mostra ancora "NO_ID" e nel mio codice ho findViewById(R.id.test1)ed findViewById(R.id.test2)entrambi restituiscono null.

Qualcuno può aiutarmi con il mio problema?


6
Ai tuoi ID manca il @simbolo.
AutonomousApps

Risposte:


288

Specificare l'ID nel file <include>

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

Quindi usane due findViewByIdper accedere ai campi nel layout

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

Usando questo approccio, puoi accedere a qualsiasi campo in qualsiasi inclusione che hai.


18
Questo metodo mi restituisce un valore nullo per l'oggetto test1View.
Nirav Shah

4
Non vedo davvero la differenza, puoi spiegare?
Goddchen

30
Ho scoperto che se il layout che abbiamo incluso utilizza l'unione, questo non aiuterà. Ma nel caso in cui l'unione non venga utilizzata, funziona.
Zlatko

@Zlatko Sì, e questo non può funzionare mergenemmeno in teoria, perché il risultato dell'inclusione di una mergenon è una singola vista, ma un gruppo di esse. Così è ok.
Nome visualizzato

1
Funzionerà solo nel caso in cui non venga utilizzata l'unione. In caso di unione non è possibile come specificato qui: code.google.com/p/android/issues/detail?id=36918#c3
Zahid Rasheed

61

Ho scoperto che se stai utilizzando il <merge>tag nel layout di inclusione, l'ID di inclusione viene trasferito al tag di unione che non è una visualizzazione reale.

Quindi rimuovi l'unione o sostituiscila con un layout.

Tor Norbye ha scritto :

Il <include>tag non è una visualizzazione reale, quindi findByView non lo troverà. L'attributo @id (e qualsiasi altro attributo che hai impostato sul tag include) viene invece applicato al tag radice del layout incluso. Quindi la tua attività.getView (R.id.included1) dovrebbe in effetti essere la <TextView>stessa.


3
Bene. Rimuovo il tag di unione e inizia a funzionare, ma la mia domanda qui è qual è l'uso del tag di unione se un layout di inclusione funziona senza di esso?
Ankur Chaudhary

35

Romain Guy indica che è possibile sovrascrivere l'ID di un layout incluso inserendo un android:idattributo all'interno del <include>tag.

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

1
Questo è corretto. Il modo per fare riferimento all'elemento radice nel file di layout incluso è tramite l'id dato nel tag 'include' (a meno che non venga fornito).
Tom R

1
ID in <include> = ID root nel layout incluso
Fadils

Mi sembra che se imposto prima l'id (nel tag include, sovrascrive l'id dal layout incluso, giusto?), Avrò inizialmente il tag di inclusione '@ + id / cell1' e poi il layout = ' @ layout / workspace_screen 'sovrascriverà di nuovo android: id con l'ID del layout incluso. Le risposte di @Ron Romero hanno più senso per me.
Neon Warge

14

Penso che la risposta più alta manchi il punto più importante e potrebbe indurre le persone a pensare che il <include/>tag crei una vista che contiene i contenuti di inclusione.

Il punto chiave è che l' ID di include viene passato alla vista principale del file di layout di include.

Significa che questo:

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

Diventa questo:

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

4

sì è così, ma attenzione quando il layout inserito nel campo include è personalizzato e vuoi accedere a quel layout principale. Quel layout in questo caso @ layout / test test, viene effettivamente restituito nella prima riga.

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


2

Il problema è che proviamo a utilizzare id che non è dichiarato nel file di layout corrente. Invece di dichiararlo di nuovo, è possibile fare riferimento a id semplicemente usando @+id/. Se esegui il refactoring del nome dell'ID originale tramite Android Studio, viene eseguito anche il refactoring nel layout incluso.

<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

In un caso di utilizzo, <RecyclerView>trova l'id di <include>utilizzando un'istanza di visualizzazione gonfiata, altrimenti restituirà 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

Se hai impostato l'ID su uno dei tag radice del layout incluso, puoi utilizzare quell'ID oppure puoi impostare l'ID sul layout incluso.

Ma non puoi impostare id su entrambi, potrebbe generare un'eccezione.

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

O

<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

Quando si parla di include, si ha un id nella vista principale all'interno del file di layout incluso o sulla riga di inclusione stessa e non su entrambi. Per esempio:

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

File di layout 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>

L'esempio sopra è sbagliato perché tecnicamente hai due ID dichiarati per lo stesso layout. Quindi quello che devi fare è scegliere quale elemento avrà l'id.


0

Wow, non posso credere che questa domanda non abbia ancora la risposta giusta. I tag semplici fanno schifo. Puoi cambiare solo cose che iniziano con e android:layout_che android:idnon corrispondono. Quindi la risposta è che non puoi. Scusate. Quello che puoi fare invece è creare una classe che sarà un ViewGroup che gonfierà le visualizzazioni incluse all'interno, quindi aggiungilo come tag nel tuo layout, ma questo è tutto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.