findViewById () renvoie null pour le composant personnalisé dans le XML de présentation, pas pour les autres composants

J’ai un res/layout/main.xml comprenant ces éléments et d’autres:

   

Dans mon activité onCreate, 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, AtsortingbuteSet a) et un Log.d(...) à la fin de ce constructeur apparaît avec succès dans logcat juste avant que “epic fail”.

Pourquoi foo est-il nul?

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

Fait sens, si vous ne transmettez pas les atsortingbuts, tels que l’identifiant, la vue n’aura aucun identifiant et ne sera donc pas trouvable en utilisant cet identifiant. 🙂

J’ai eu le même problème. Mon erreur était la suivante: 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 dispositif de gonflage pour “charger” la vue depuis un fichier XML, la dernière ligne était incorrecte. Pour le résoudre, 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.

Il semble y avoir une variété de raisons. Je viens d’utiliser “Clean …” dans Eclipse pour résoudre un problème similaire. (FindViewByID avait fonctionné avant et pour une raison quelconque a commencé à renvoyer null.)

J’ai le même problème parce que, dans mon affichage personnalisé, j’ai annulé le constructeur, mais j’ai invoqué le super contructor sans attrs paramete. C’est du copier coller)

Ma version précédente de constructeur:

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

Maintenant j’ai:

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

Et ça marche!

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

Si vous avez plusieurs versions de mise en page (selon les densités d’écran, les versions du SDK), assurez-vous qu’elles incluent toutes l’élément que vous recherchez.

Dans mon cas, findViewById renvoyait null car mon affichage personnalisé ressemblait à ceci dans le fichier XML principal:

   

et j’ai découvert que lorsque j’ai ajouté les trucs xmlns cela fonctionnait comme ceci:

   

Assurez-vous que l’ setContentView(R.layout.main) appelle avant l’ findViewById(...) ;

Pour moi, le problème a été résolu lorsque j’ai ajouté le dossier res à la source dans Java Build Path dans les parameters du projet.

J’ai rencontré le même problème il y a quelque temps lorsque j’ai ajouté une vue personnalisée via le XML de mise en page, puis j’ai essayé de joindre un rappel ailleurs dans l’application …

J’ai créé une vue personnalisée et l’ai ajoutée à mon “layout_main.xml”

 public class MUIComponent extends SurfaceView implements SurfaceHolder.Callback { public MUIComponent (Context context, AtsortingbuteSet attrs ) { super ( context, attrs ); } // .. } 

Et dans l’activité principale, je voulais attacher des rappels et obtenir des références aux éléments de l’interface utilisateur à partir du XML.

 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... MUIInitializer muiInit = new MUIInitializer(); muiInit.setupCallbacks(this); muiInit.intializeFields(this); } } 

L’initialisateur ne faisait rien d’extraordinaire, mais les modifications qu’il essayait d’apporter à la vue personnalisée (MUIComponent) ou à d’autres éléments d’interface utilisateur non personnalisés n’apparaissaient tout simplement pas dans l’application.

 public class MUIInitializer { // ... public void setupCallbacks ( Activity mainAct ) { // This does NOT work properly // - The object instance returned is technically an instance of my "MUICompnent" view // but it is a *different* instance than the instance created and shown in the UI screen // - Callbacks never get sortingggered, changes don't appear on UI, etc. MUIComponent badInst = (MUIComponent) mainAct.findViewById(R.id.MUIComponent_TESTSURF); // ... // This works properly LayoutInflater inflater = (LayoutInflater) mainAct.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View inflatedLayout = inflater.inflate ( R.layout.activity_main, null ); MUIComponent goodInst = (MUIComponent) inflatedLayout.findViewById(R.id.MUIComponent_TESTSURF); // Add callbacks // ... } } 

La différence entre “badInst” et “goodInst” est la suivante:

  • badInst utilise le findViewByID de l’activité
  • goodInst gonfle la mise en page et utilise la mise en page gonflée pour faire la recherche

Cela m’est arrivé avec un composant personnalisé pour Wear, mais c’est un conseil générique. Si vous utilisez un Stub (par exemple, si j’utilisais WatchViewStub ), vous ne pouvez pas mettre l’appel à findViewById() n’importe où. Tout ce qui se trouve à l’intérieur du stub doit être gonflé en premier, ce qui ne se produit pas seulement après setContentView() . Ainsi, vous devriez écrire quelque chose comme ça pour attendre que cela se produise:

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_wear); final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub); stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() { @Override public void onLayoutInflated(WatchViewStub stub) { myCustomViewInst = (MyCustomView) findViewById(R.id.my_custom_view); ... 

Mon problème était une faute de frappe. J’avais écrit android.id (point) au lieu d’ android:id . : P

Apparemment, il n’y a pas de vérification de syntaxe dans mon composant xml personnalisé. 🙁

Eu le même problème.

J’ai eu la disposition avec peu d’enfants. Du constructeur de l’un d’eux, j’essayais d’obtenir une référence (en utilisant context.findViewById) à un autre enfant. Cela ne marchait pas car le deuxième enfant était défini plus loin dans la présentation.

Je l’ai résolu comme ceci:

 setContentView(R.layout.main); MyView first = findViewById(R.layout.first_child); first.setSecondView(findViewById(R.layout.second_child)); 

Cela fonctionnerait aussi bien si l’ordre des enfants était contraire, mais je suppose que cela devrait généralement être fait comme ci-dessus.

La méthode findViewById() renvoie parfois null lorsque la racine de la mise en page ne possède aucun atsortingbut android:id . L’assistant Eclipse pour générer un fichier XML d’agencement ne génère pas automatiquement l’atsortingbut android:id pour l’élément racine.

Dans mon cas, la vue était dans le parent NON dans la vue que j’essayais de l’appeler. Donc, dans la vue enfant, je devais appeler:

 RelativeLayout relLayout = (RelativeLayout) this.getParent(); View view1 = relLayout.findViewById(R.id.id_relative_layout_search); 

L’option «propre» a fonctionné pour moi.

Dans mon cas, la cause première est que le code source réside sur un partage réseau et que mon poste de travail et mon serveur de fichiers n’ont pas été synchronisés correctement et ont dérivé de 5 secondes. Les horodatages des fichiers créés par Eclipse sont antérieurs (car ils sont atsortingbués par le serveur de fichiers) par rapport à l’horloge du poste de travail, ce qui empêche Eclipse de résoudre les dépendances entre les fichiers générés et les fichiers sources. Dans ce cas, un «nettoyage» semble fonctionner, car il oblige une reconstruction complète au lieu d’une génération incrémentielle qui dépend des horodatages incorrects.

Une fois que j’ai corrigé les parameters NTP sur mon poste de travail, le problème ne s’est jamais reproduit. Sans les parameters NTP appropriés, cela se produirait toutes les quelques heures, car les horloges dérivent rapidement.

Ajouter une autre erreur sortingviale aux réponses à rechercher:

Vérifiez que vous êtes en train de modifier le bon fichier XML de mise en page …

J’ai eu le même problème parce que j’ai oublié de mettre à jour l’id de vue dans tous mes dossiers de mise en page.