Zuallererst: Ja, ich habe alle anderen Themen zu diesem Thema gelesen. Und nicht nur die von dieser Seite ... (Sie sehen, ich bin ein wenig frustriert)
Die meisten von ihnen haben den Rat, sie android:id
nicht nur id
in der XML-Datei zu verwenden. Ich tat.
Von anderen habe ich gelernt, dass View.findViewById
das anders funktioniert als Activity.findViewById
. Ich habe auch damit umgegangen.
In meinem location_layout.xml
benutze ich:
<FrameLayout .... >
<some.package.MyCustomView ... />
<LinearLayout ... >
<TextView ...
android:id="@+id/txtLat" />
...
</LinearLayout>
</FrameLayout>
In meiner Tätigkeit mache ich:
...
setContentView( R.layout.location_layout );
und in meiner benutzerdefinierten Ansichtsklasse:
...
TextView tv = (TextView) findViewById( R.id.txtLat );
was zurückkehrt null
. Dabei funktioniert meine Aktivität einwandfrei. So ist es vielleicht wegen der Activity.findViewById
und View.findViewById
Unterschiede. Also habe ich den Kontext, der an den Konstruktor der Zollansicht übergeben wurde, lokal gespeichert und versucht:
...
TextView tv = (TextView) ((Activity) context).findViewById( R.id.txtLat );
was auch zurückkehrte null
.
Dann habe ich meine benutzerdefinierte Ansicht geändert, um sie ViewGroup
stattdessen zu erweitern, View
und die so geändert location_layout.xml
, dass TextView
sie ein direktes untergeordnetes Element meiner benutzerdefinierten Ansicht ist, sodass die Ansicht View.findViewById
wie angenommen funktionieren soll. Überraschung: Es hat nichts gelöst.
Also, was zum Teufel mache ich falsch?
Ich freue mich über Kommentare.
quelle
Antworten:
Möglicherweise, weil Sie es zu früh anrufen. Warten Sie bis
onFinishInflate()
. Hier ist ein Beispielprojekt, das zeigt, wie ein BenutzerView
auf seine Inhalte zugreift.quelle
onFinishInflate()
.Möglicherweise rufen Sie an,
findViewById
bevor Sie anrufensetContentView
? Wenn dies der Fall ist, rufen SiefindViewById
NACH dem Anruf ansetContentView
quelle
Stellen Sie sicher, dass Sie nicht mehrere Versionen Ihres Layouts für unterschiedliche Bildschirmdichten haben. Ich bin einmal auf dieses Problem gestoßen, als ich einem vorhandenen Layout eine neue ID hinzugefügt habe, habe aber vergessen, die HDPI-Version zu aktualisieren. Wenn Sie vergessen, alle Versionen der Layoutdatei zu aktualisieren, funktioniert dies für einige Bildschirmdichten, für andere jedoch nicht.
quelle
FindViewById kann null sein, wenn Sie in einer benutzerdefinierten Ansicht den falschen Superkonstruktor aufrufen. Das ID-Tag ist Teil von attrs. Wenn Sie also attrs ignorieren, löschen Sie die ID.
Das wäre falsch
Das ist richtig
quelle
In meinem Fall hatte ich 2 Aktivitäten in meinem Projekt
main.xml
undmain2.xml
. Von Anfang anmain2
war eine Kopiemain
, und alles funktionierte gut, bis ich neu hinzugefügtTextView
zumain2
, so dass dieR.id.textview1
für den Rest der App zur Verfügung stand. Dann habe ich versucht, es durch Standardaufrufe abzurufen:und es war immer null. Es stellte sich heraus, dass
onCreate
ich im Konstruktor nicht instanziiertemain2
, sondern den anderen. Ich hatte:anstatt
Ich bemerkte dies, nachdem ich hier auf der Website angekommen war.
quelle
Neben den an anderer Stelle erwähnten klassischen Ursachen:
setContentView()
habenfindViewById()
id
gewünschte Element in der Ansicht oder dem Layout enthalten ist, die Sie angegeben habensetContentView()
id
nicht versehentlich in verschiedenen Layouts dupliziert wirdIch habe eine für benutzerdefinierte Ansichten in Standardlayouts gefunden, die gegen die Dokumentation verstößt:
Theoretisch können Sie eine benutzerdefinierte Ansicht erstellen und einem Layout hinzufügen ( siehe hier ). Ich habe jedoch festgestellt, dass in solchen Situationen das
id
Attribut manchmal für alle Ansichten im Layout mit Ausnahme der benutzerdefinierten Ansichten funktioniert. Die Lösung, die ich benutze, ist:FrameLayout
mit denselben Layout-Eigenschaften, die die benutzerdefinierte Ansicht haben soll.id
Sagen Sie es angemessen , sagen wirframe_for_custom_view
.In
onCreate
:Dadurch wird die benutzerdefinierte Ansicht in den Rahmen eingefügt.
quelle
quelle
Eine Antwort für diejenigen, die ExpandableListView verwenden und diese Frage anhand des Titels beantworten.
Ich hatte diesen Fehler beim Versuch, mit TextViews in meinen untergeordneten und Gruppenansichten als Teil einer ExpandableListView-Implementierung zu arbeiten.
Sie können in Ihren Implementierungen der Methoden getChildView () und getGroupView () Folgendes verwenden.
Ich habe das hier gefunden .
quelle
Ich bin ziemlich neu in Android / Eclipse, aus Versehen habe ich
activity_main.xml
stattdessen das UI-Zeug hinzugefügtfragment_main.xml
. Ich habe einige Stunden gebraucht, um das herauszufinden ...quelle
FWIW, ich sehe nicht, dass irgendjemand dies auf die gleiche Weise gelöst hat, wie ich es brauchte. Keine Beschwerden zur Kompilierungszeit, aber ich bekam zur Laufzeit eine Nullansicht und rief die Dinge in der richtigen Reihenfolge auf. Das heißt, findViewById () nach setContentView (). Das Problem stellte sich heraus, dass meine Ansicht in content_main.xml definiert ist, aber in meiner activity_main.xml fehlte mir diese eine Anweisung:
Als ich das zu activity_main.xml hinzufügte, kein NullPointer mehr.
quelle
Ich hatte das gleiche Problem. Ich habe eine Bibliothek eines Drittanbieters verwendet, mit der Sie den Adapter für eine GridView überschreiben und für jede GridView-Zelle ein eigenes Layout angeben können.
Endlich wurde mir klar, was los war. Eclipse verwendete weiterhin die Layout-XML-Datei der Bibliothek für jede Zelle in GridView, obwohl dies keinen Hinweis darauf gab. In meinem benutzerdefinierten Adapter wurde angezeigt, dass die XML-Ressource aus meinem eigenen Projekt verwendet wurde, obwohl dies zur Laufzeit nicht der Fall war.
Ich habe also sichergestellt, dass sich meine benutzerdefinierten XML-Layouts und -IDs von denen unterscheiden, die sich noch in der Bibliothek befinden. Ich habe das Projekt bereinigt und dann die richtigen benutzerdefinierten Layouts in meinem Projekt gelesen.
Kurz gesagt, seien Sie vorsichtig, wenn Sie den Adapter einer Drittanbieter-Bibliothek überschreiben und Ihre eigene Layout-XML für den zu verwendenden Adapter angeben. Wenn Ihr Layout in Ihrem Projekt denselben Dateinamen wie das in der Bibliothek hat, tritt möglicherweise ein wirklich schwer zu findender Fehler auf!
quelle
In meinem speziellen Fall habe ich versucht, einer ListView eine Fußzeile hinzuzufügen. Der folgende Aufruf in onCreate () gab null zurück.
Wenn Sie dies ändern, um die Fußzeilenansicht aufzublähen, anstatt sie anhand der ID zu finden, wurde dieses Problem behoben.
quelle
In meinem Fall habe ich ExpandableListView verwendet und festgelegt
android:transcriptMode="normal"
. Dies führte dazu, dass nur wenige Kinder in einer erweiterbaren Gruppe verschwanden und ich immer eine NULL-Ausnahme bekam, wenn ich die Liste scrollte.quelle
Für mich hatte ich zwei XML-Layouts für dieselbe Aktivität - eines im Hochformat und eines im Querformat. Natürlich hatte ich die ID eines Objekts in der Querformat-XML geändert, aber vergessen, dieselbe Änderung in der Hochformatversion vorzunehmen. Stellen Sie sicher, dass Sie, wenn Sie eine ändern, dasselbe mit der anderen XML tun. Andernfalls wird keine Fehlermeldung angezeigt, bis Sie sie ausführen / debuggen und die ID, die Sie nicht geändert haben, nicht gefunden wird. Oh dumme Fehler, warum musst du mich so bestrafen?
quelle
Legen Sie den Aktivitätsinhalt aus einer Layoutressource fest. dh
setContentView(R.layout.basicXml)
;quelle
Zusätzlich zu den oben genannten Lösungen stellen Sie sicher, dass der
tools:context=".TakeMultipleImages"
Wert im Layout derselbe Wert in der Datei mainfest.xml ist:android:name=".TakeMultipleImages"
für dasselbe Aktivitätselement. Es tritt auf, wenn Sie mit Kopieren und Einfügen neue Aktivitäten erstellenquelle
Ich habe das gleiche Problem, aber ich denke, es lohnt sich, es mit euch zu teilen. Wenn Sie ViewById in einem benutzerdefinierten Layout finden müssen, zum Beispiel:
Sie können die Ansicht im Konstruktor nicht erhalten. Sie sollten findViewById aufrufen, nachdem die Ansicht aufgeblasen wurde. Dies ist eine Methode, die Sie überschreiben können
onFinishInflate
quelle
Ich wollte nur meinen speziellen Fall hier reinwerfen. Könnte jemandem auf der ganzen Linie helfen.
Ich habe die Direktive in meinem Android UI XML wie folgt verwendet:
Übergeordnete Ansicht:
Untergeordnete Ansicht (retry_button):
.findViewById (R.id.retry) würde immer null zurückgeben. Wenn ich jedoch die ID aus der untergeordneten Ansicht in das Include-Tag verschoben habe, hat sie funktioniert.
Feste Eltern:
Festes Kind:
quelle
Mein Fall ist keiner wie oben, keine Lösungen haben funktioniert. Ich gehe davon aus, dass meine Ansicht zu tief in der Layouthierarchie lag. Ich habe es eine Ebene nach oben verschoben und es war nicht mehr null.
quelle
In meinem Fall hatte ich das Layout aufgeblasen, aber die untergeordneten Ansichten gaben null zurück. Ursprünglich hatte ich das:
Als ich es jedoch wie folgt änderte, funktionierte es:
Der Schlüssel bestand darin, speziell auf das bereits aufgeblasene Layout zu verweisen, um die untergeordneten Ansichten zu erhalten. Das heißt, um hinzuzufügen
footerView
:quelle
Nach meiner Erfahrung kann dies auch passieren, wenn Ihr Code nach OnDestroyView aufgerufen wird (wenn sich das Fragment auf dem Backstack befindet). Wenn Sie die Benutzeroberfläche bei Eingabe von einem BroadCastReceiver aktualisieren, sollten Sie prüfen, ob dies der Fall ist .
quelle
LUFEN SIE DAS LAYOUT AUF !! (welches die ID enthält)
In meinem Fall hat findViewById () null zurückgegeben, da das Layout, in das das Element geschrieben wurde, nicht aufgeblasen wurde ...
Z.B. fragment_layout.xml
findViewById (R.id.listview) gab null zurück, da ich inflater.inflate nicht ausgeführt hatte (R.layout.fragment_layout, ..., ...); bevor.
Hoffe, diese Antwort hilft einigen von euch.
quelle
Mein Fix war, nur das Projekt zu bereinigen.
quelle
findViewById kann auch null zurückgeben, wenn Sie sich in einem Fragment befinden. Wie hier beschrieben: findViewById in Fragment
Sie sollten getView () aufrufen, um die Ansicht der obersten Ebene innerhalb eines Fragments zurückzugeben. Dann finden Sie die Layoutelemente (Schaltflächen, Textansichten usw.)
quelle
Ich habe versucht, all das zu tun, nichts hat funktioniert. Also musste ich mein ImageView statisch machen
public static ImageView texture;
und danntexture = (ImageView) findViewById(R.id.texture_back);
denke ich nicht, dass es ein guter Ansatz ist, aber das hat wirklich für meinen Fall funktioniert :)quelle
In meinem Fall hat findViewById null zurückgegeben, als ich den Aufruf von einem übergeordneten Objekt in ein vom übergeordneten Objekt instanziiertes Adapterobjekt verschoben habe. Nachdem ich die hier aufgeführten Tricks erfolglos ausprobiert hatte, verschob ich die findViewById zurück in das übergeordnete Objekt und übergab das Ergebnis als Parameter während der Instanziierung des Adapterobjekts. Zum Beispiel habe ich dies im übergeordneten Objekt getan:
Dann habe ich den hdSpinner als Parameter beim Erstellen des Adapterobjekts übergeben:
quelle
Es stürzte für mich ab, weil eines der Felder in meiner Aktivitäts-ID mit der ID in einer anderen Aktivität übereinstimmte. Ich habe es behoben, indem ich eine eindeutige ID angegeben habe.
In meiner loginActivity.xml-Passwortfeld-ID war "Passwort". In meiner Registrierungsaktivität habe ich es einfach behoben, indem ich die ID r_password angegeben habe, dann hat es kein Null-Objekt zurückgegeben:
quelle
Ich hatte ein ähnliches Problem, als ich versuchte, eine benutzerdefinierte Ansicht für a zu erstellen
ListView
.Ich habe es einfach dadurch gelöst:
quelle
Möglichkeiten zum Debuggen und Finden des Problems:
In meinem Fall habe ich activity_main.xml sowohl in meinem App-Modul als auch in meinem Bibliotheksmodul verwendet. Als ich die obigen Schritte ausführte, wurde anstelle des Layouts, das ich in der Bibliothek entworfen hatte, das Layout im App-Modul aufgeblasen.
Also habe ich den Dateinamen activity_main.xml in activity_main_lib.xml geändert.
Stellen Sie daher sicher, dass Sie in Ihrem gesamten Projekt keine doppelten Layoutnamen haben .
quelle