2010-01-21 9 views
16

Sappiamo tutti che quando si genera un ID per Android utilizzandoAndroid meccanismo di id di collisione per R.java

@+id/foo 

Android crea per noi una voce in R.java come:

public static final class id { 
     public static final int foo=0x7f060005; 
} 

Che cosa succede se c'è una collisione di nome in diversi file xml (diciamo, all'interno di due layout)? Il meccanismo @ + id ci assicura di sovrascrivere il nome dell'ID se ne esiste ancora un altro, ma quale viene generato in R.java per noi?

+2

Dai documenti: Un ID non deve essere univoco nell'intero albero, ma deve essere univoco all'interno della parte dell'albero che stai cercando (che potrebbe essere spesso l'intero albero, quindi è meglio essere completamente unico quando possibile). – Lucas

risposta

25

La sintassi @+id/foo verrà aggiunta se l'ID non esiste o utilizza l'ID esistente.
Quando si trovaViewById, funzionerà sulla vista su cui si chiama il metodo.

Quindi, se hai viste nidificate, il tuo ID sarà univoco per ogni vista. ad es. View1 -> View2 hanno entrambi foo. View2.findViewById(R.id.foo)

modifica: Credo che la cosa principale da menzionare sia che due layout non possono avere lo stesso id. Per ulteriori informazioni sul vincolo ID: http://d.android.com/guide/topics/ui/declaring-layout.html

+3

Il secondo punto è particolarmente importante se si utilizza include, poiché riutilizzare lo stesso layout con include spesso si tradurrà nello stesso ID utilizzato in più rami dell'albero View. –

+0

Ciò significa che R.java agisce solo come contenitore del nome? Cosa succede se dichiaro due pulsanti in due file xml diversi con lo stesso nome ID e cerco di recuperarlo in un'attività? Modifica: il collegamento appena aggiunto mi fa pensare che un Layout funge anche da "spazio dei nomi" per gli ID dichiarati al suo interno. – dgraziotin

+0

+1 per un buon punto. Ho aggiornato la mia risposta con un link alla guida che menzionava specificamente questo. Penso che possa essere un po 'di confusione per uno sviluppatore (specialmente uno sviluppatore web) che si è abituato a usare id univoci per elementi in un'applicazione, come elementi in una pagina web. –

2

Penso che riutilizzi semplicemente l'identificatore se è già stato generato. Tendo a riutilizzare gli ID un po 'e non ho mai incontrato un problema.

+0

Riutilizza significa che sovrascrive la voce in R.java se ne è presente un'altra. Come fa Android decidere quale mantenere e quale eliminare, in fase di compilazione? – dgraziotin

+2

Questa domanda non ha senso: se hanno lo stesso nome, hanno lo stesso valore e viceversa. Android non "mantiene" uno o "elimina" uno. @ + id crea un identificatore * se non esiste ancora. * –

+2

La mia domanda è nata a causa di un fraintendimento del meccanismo R.java: ho pensato che R.java contenga "puntatori" agli oggetti View. Ora so che è solo un contenitore identificativo. Pertanto, il meccanismo @ + ID è completamente logico ora. – dgraziotin

4

ho provato una semplice applicazione Ciao Mondo con il seguente codice XML:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" > 

<TextView 
     android:id="@+id/textview" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:text="text1" 
/> 

<TextView 
     android:id="@+id/textview" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:text="text2" 
/> 

</LinearLayout> 

Entrambi i miei textviews avere lo stesso ID. Compila bene, funziona bene, rende sia le TextView, e quando faccio un findViewByid() il primo viene trovato e tutte le mie chiamate di funzione come setText vengono applicate ad esso. Idealmente, l'AAPT dovrebbe prenderlo ma apparentemente no. Non spezzerà qualcosa di terribile a meno che il programmatore non si affidi agli id. Quindi è un po 'come dire: se sei così stupido da scrivere un codice del genere, meriti di schiantarti.

L'AAPT non si preoccuperà troppo di questo. Per questo, è come una semplice estensione di Views senza ID espliciti forniti dal programmatore.

+0

1 su per lo sforzo di fare un test su di esso e condividere i dettagli. –

Problemi correlati