Dans un fichier XML, nous pouvons affecter un ID à une vue telle que Android:id="@+id/something"
, puis appeler findViewById()
, mais lors de la création d'une vue par programme, comment puis-je affecter un ID?
Je pense que setId()
n'est pas la même chose que l'affectation par défaut. setId()
est extra.
Quelqu'un peut-il me corriger?
id
overviewUn Android id
est un entier couramment utilisé pour identifier les vues. id
peut être assigné via XML (si possible) et via code (par programmation). Le id
est très utile pour obtenir des références pour le nom défini par XML View
s généré par un Inflater
(comme en utilisant setContentView
.)
id
via XML
Android:id="@+id/
somename"
à votre vue.Android:id
se voit attribuer un niqueint
à utiliser dans le code.int
de Android:id
dans le code en utilisant "R.id.
somename" (en fait, une constante.)int
peut changer de build en build donc ne jamais copier un identifiant de gen/
package.name/R.Java
_, utilisez simplement "R.id.
somename".id
attribué à un Preference
dans XML n'est pas utilisé lorsque Preference
génère son View
.)id
via code (par programme)id
s à l'aide de someView.setId(
int);
int
doit être positif, mais est sinon arbitraire - il peut être ce que vous voulez (continuez à lire si cela est effrayant).id
sXML
- assigné id
s sera unique.id
s assigné par code ne pas doit être uniqueid
s assigné par code peut (théoriquement) entrer en conflit avec XML
- assigné id
s.id
s conflictuels n’auront pas d’importance s’ils sont interrogés correctement (continuer à lire) .id
s ne comptent pasfindViewById(int)
va parcourir récursivement la profondeur d'abord dans la hiérarchie de la vue spécifiée et renvoie le premier View
qu'il trouve avec un id
correspondant.id
s assigné par code avant un id
défini par XML dans la hiérarchie, findViewById(R.id.somename)
retournera toujours la vue définie par XML afin que id
'd.ID
sViewGroup
vide avec id
.LinearLayout
avec Android:id="@+id/placeholder"
. ViewGroup
avec View
s.id
s qui conviennent à chaque vue.Interrogez ces vues enfant à l'aide de placeholder.findViewById (convenientInt);
L'API 17 a introduit View.generateViewId()
qui permet de générer un identifiant unique.
Si vous choisissez de conserver des références à vos vues, veillez à les instancier avec getApplicationContext()
et à définir chaque référence sur null dans onDestroy
. Apparemment fuir le Activity
(s'accrocher après qu'il soit détruit) est inutile .. :)
Android:id
à utiliser dans le code API 17 introduite View.generateViewId()
qui génère un identifiant unique. (Merci à take-chances-make-changes pour l'avoir signalé.) *
Si votre ViewGroup
ne peut pas être défini via XML (ou si vous ne le souhaitez pas), vous pouvez réserver l'ID via XML pour vous assurer qu'il reste unique:
Ici, valeurs/ids.xml définit un nom personnalisé id
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="reservedNamedId" type="id"/>
</resources>
Ensuite, une fois que le ViewGroup ou View a été créé, vous pouvez attacher l'id personnalisé
myViewGroup.setId(R.id.reservedNamedId);
id
en conflitPour plus de clarté au moyen d'un exemple obscurcissant, examinons ce qui se passe lorsqu'il existe un conflit id
dans les coulisses.
layout/mylayout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical" >
<LinearLayout
Android:id="@+id/placeholder"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:orientation="horizontal" >
</LinearLayout>
Pour simuler un conflit, disons que notre dernière construction affectée R.id.placeholder
(@+id/placeholder
) et une valeur int
de 12
..
Ensuite, MyActivity.Java définit quelques vues ajoutées par programme (via le code):
int placeholderId = R.id.placeholder; // placeholderId==12
// returns *placeholder* which has id==12:
ViewGroup placeholder = (ViewGroup)this.findViewById(placeholderId);
for (int i=0; i<20; i++){
TextView tv = new TextView(this.getApplicationContext());
// One new TextView will also be assigned an id==12:
tv.setId(i);
placeholder.addView(tv);
}
Donc, placeholder
et l’un de nos nouveaux TextView
s ont tous les deux un id
de 12! Mais ce n'est pas vraiment un problème si nous interrogeons les vues enfants de l'espace réservé:
// Will return a generated TextView:
placeholder.findViewById(12);
// Whereas this will return the ViewGroup *placeholder*;
// as long as its R.id remains 12:
Activity.this.findViewById(12);
*Pas si mal
Vous pouvez simplement utiliser la View.setId(integer)
pour cela. Dans le XML, même si vous définissez un identifiant de chaîne, celui-ci est converti en un entier. Pour cette raison, vous pouvez utiliser n'importe quel entier (positif) pour le Views
que vous ajoutez par programme.
Selon la documentation
View
L'identifiant ne doit pas nécessairement être unique dans la hiérarchie de cette vue. L'identifiant doit être un nombre positif.
Vous pouvez donc utiliser n'importe quel entier positif, mais dans ce cas, il peut y avoir des vues avec des identifiants équivalents. Si vous souhaitez rechercher une vue dans la hiérarchie, un appel à setTag avec certains objets clés peut s'avérer utile.
Crédits à cette réponse .
Oui, vous pouvez appeler setId(value)
dans n'importe quelle vue avec une valeur entière (positive) de votre choix, puis la trouver dans le conteneur parent à l'aide de findViewById(value)
. Notez qu'il est valide d'appeler setId()
avec la même valeur pour différentes vues frères, mais findViewById()
ne renverra que la première.