94 votes

findViewById() retourne null pour le composant personnalisé dans le layout XML, mais pas pour les autres composants.

J'ai un res/layout/main.xml y compris ces éléments et d'autres :

<some.package.MyCustomView android:id="@+id/foo" (some other params) />
<TextView android:id="@+id/boring" (some other params) />

Dans le onCreate de mon activité, je fais ceci :

setContentView(R.layout.main);
TextView boring = (TextView) findViewById(R.id.boring);
// ...find other elements...
MyCustomView foo = (MyCustomView) findViewById(R.id.foo);
if (foo == null) { Log.d(TAG, "epic fail"); }

Les autres éléments sont trouvés avec succès, mais foo revient nul. MyCustomView a un constructeur MyCustomView(Context c, AttributeSet a) et un Log.d(...) à la fin de ce constructeur apparaît avec succès dans logcat juste avant le "epic fail".

Pourquoi est-ce que foo nul ?

186voto

Chris Boyle Points 6194

Parce que dans le constructeur, j'avais super(context) au lieu de super(context, attrs) .

C'est logique, si vous ne passez pas les attributs, tels que l'id, alors la vue n'aura pas d'id et ne pourra donc pas être trouvée en utilisant cet id. :-)

4 votes

Aussi, ne devriez-vous pas des lignes comme (MyCustomView) foo = findViewById(R.id.foo); être MyCustomView foo = (MyCustomView) findViewById(R.id.foo); ?

3 votes

J'ai eu le même problème, dans mon cas j'avais oublié le setContentView() . XD

0 votes

Il existe un bel exemple de ce type d'action sur vogella.com : vogella.com/articles/AndroidCustomViews/article.html

28voto

J'ai eu le même problème, parce que dans ma vue personnalisée, j'ai surchargé le constructeur, mais j'ai invoqué le super constructeur sans la balise attrs paramètre. (C'était une erreur de copier/coller).

Ma version précédente du constructeur :

public TabsAndFilterRelativeLayout(Context context, AttributeSet attrs) {
    super(context);
}

Maintenant, je l'ai :

public TabsAndFilterRelativeLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

Et ça marche !

18voto

jellyfish Points 1215

Il semble qu'il y ait une variété de raisons. Je viens d'utiliser "Clean..." dans Eclipse pour résoudre un problème similaire. (FindViewByID avait fonctionné auparavant et pour une raison quelconque, il a commencé à retourner null).

1 votes

Apparemment, le problème sous-jacent est que les identifiants R.java sont cassés ou ne sont pas mis à jour. Je l'ai remarqué non seulement avec les ID, mais aussi dans d'autres cas, par exemple une mauvaise chaîne affichée dans un TextView, etc. Je ne sais pas vraiment pourquoi cela se produit, cependant.

18voto

Vincent Points 463

J'ai eu le même problème. Mon erreur était que : J'ai écrit

        LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View layout=inflater.inflate(R.layout.dlg_show_info, null);
        alertDlgShowInfo.setView(layout);
        TableRow trowDesc=(TableRow)findViewById(R.id.trowDesc);

et comme j'ai utilisé un inflateur pour "charger" la vue à partir d'un fichier XML, la dernière ligne était fausse. Pour résoudre ce problème, j'ai dû écrire :

TableRow trowDesc=(TableRow)layout.findViewById(R.id.trowDesc);

J'ai écrit ma solution, au cas où quelqu'un aurait le même problème.

11voto

Daniel Points 880

Même problème, mais solution différente : Je n'ai pas appelé

setContentView(R.layout.main)

AVANT j'ai essayé de trouver la vue comme indiqué aquí

0 votes

Je pense que c'est la solution si vous obtenez un élément sur une autre vue au lieu de la vue connexe actuelle.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X