GetActivity () findViewById gibt null zurück, aufgerufen von fragment onActivityCreated

Ich folge der Kontaktpersonen-Unterrichtsstunde beim Abrufen von Kontakten und deren Darstellung mit Fragmenten. Als Referenz habe ich die API-Ebene auf 16 (Android 4.1) gesetzt.

Ich habe dieses Tutorial meistens dem Brief beigebracht, mit einigen bemerkenswerten Ausnahmen. Zum Beispiel importiere ich von mypackage.R anstatt android.R .

Mein Problem ist in meinem onActivityCreated Handler in meinem ListContactsFragment :

 public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Initializes the loader getLoaderManager().initLoader(0, null, this); // Gets the ListView from the View list of the parent activity View mContactsListView = getActivity().findViewById(R.layout.contacts_list_view); mContactsList = (ListView) mContactsListView; // Gets a CursorAdapter mCursorAdapter = new SimpleCursorAdapter( getActivity(), R.layout.contacts_list_item, null, FROM_COLUMNS, TO_IDS, 0); // Sets the adapter for the ListView mContactsList.setAdapter(mCursorAdapter); // Set the item click listener to be the current fragment. mContactsList.setOnItemClickListener(this); } 

View mContactsListView ist null, dh findViewById hat nicht funktioniert.

Meine übergeordnete Aktivität ist ein Standard, das von eclipse erstellt wurde. Dazu habe ich zwei Dinge gemacht:

  1. Ersetzte import android.app.Activity mit android.support.v4.app.FragmentActivity , um die android.support.v4.app.FragmentActivity zu verhindern, die passiert, wenn Sie dies nicht tun.
  2. Ich habe mein Fragment in das XML importiert.

Meine activity_list_contacts.xml sieht so aus:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".ListContactsActivity" > <fragment android:name="mypackage.ListContactsFragment" android:id="@+id/contacts_list_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout> 

Die passende Aktivität, nur für den Fall:

 public class ListContactsActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list_contacts); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.list_contacts, menu); return true; } } 

Und contacts_list_view.xml :

 <?xml version="1.0" encoding="utf-8"?> <ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent"/> 

Also meine Frage ist, was mache ich falsch für findViewById nicht meine Ansicht zu finden?

Dinge, die ich ausprobiert habe (die meisten von ihnen sind akzeptierte Antworten auf Fragen, die fast wie ein Duplikat zu diesem aussehen):

  • Lesen des Dokuments, das ich kopiert und von Wort für Wort eingefügt habe.
  • Versuche zu getView().findViewById() wie in dieser Frage vorgeschlagen . Das gibt auch null zurück.
  • Mit findViewById(R.id.contacts_list_view); Stattdessen, wie durch diese Antwort vorgeschlagen . Das kommt nicht zurück; Stattdessen verursacht es eine ClassCastException in diesem android.support.v4.app.NoSaveStateFrameLayout konnte nicht zu android.widget.ListView .
  • Ich habe gelesen, dass manchmal der Fragment Rückruf für die Erstellung vor der Anbindung an die Aktivität erfolgt. Also habe ich den Handler der onAttach Methode so hinzugefügt:

     @Override public void onAttach(Activity activity) { super.onAttach(activity); View mContactsListView = activity.findViewById(R.id.contacts_list_view); mContactsList = (ListView) mContactsListView; // Gets a CursorAdapter mCursorAdapter = new SimpleCursorAdapter( getActivity(), R.layout.contacts_list_item, null, FROM_COLUMNS, TO_IDS, 0); // Sets the adapter for the ListView mContactsList.setAdapter(mCursorAdapter); // Set the item click listener to be the current fragment. mContactsList.setOnItemClickListener(this); } 

    Du hast es erraten – immer noch null.

Also an diesem Punkt bin ich ein wenig verloren. Ich habe zwei Fragen:

  1. Was mache ich falsch (bitte zusätzliche Informationen in Kommentare anfordern, wenn ich nicht genug bereitgestellt habe)?
  2. Ist es vorzuziehen, den Adapter-Setup in onAttach zu verlassen, oder wo das Tutorial sagt.

  • Android: Unterschied zwischen unsichtbar und weg?
  • (Kann keine ID-Referenz finden) Keine Ressource entspricht dem Vornamen bei
  • Keine Ressource-ID gefunden für Attribut 'showAsAction' im Paket 'android'
  • Fügen Sie benutzerdefiniertes Layout zu Symbolleiste hinzu
  • Erhalte den Attributnamen aus dem String-Array
  • Umschaltfarbe einer Progressbar programmgesteuert
  • Entwerfen Sie ein Layout wie unten Bild mit Bild Schaltflächen in Android
  • Animierte zweischichtige Gegenstände Gegen-Wabe
  • 4 Solutions collect form web for “GetActivity () findViewById gibt null zurück, aufgerufen von fragment onActivityCreated”

    Ich folge dem Tutorial bei developer.android.com und stieß auf das gleiche Problem.

    Schließlich bemerkte ich das in diesem Teil:

     // Gets the ListView from the View list of the parent activity mContactsList = (ListView) getActivity().findViewById(R.layout.contact_list_view); 

    Es scheint versucht, eine View zu finden, aber eine Layout id als Argument zu übergeben.

    Die Ansicht | Android referenzen sagt:

    View-IDs müssen nicht im ganzen Baum einzigartig sein, aber es ist eine gute Übung, um sicherzustellen, dass sie mindestens einmalig sind in dem Teil des Baumes, den Sie suchen.

    Also habe ich die ListView id in der ListView id in eine eindeutige geändert:

     <?xml version="1.0" encoding="utf-8"?> <ListView ... android:id="@+id/contacts_listview_a_unique_id_here" ... /> 

    Dann versuche es zu finden mit:

      mContactsList = (ListView) getActivity().findViewById(R.id.contacts_listview_a_unique_id_here); 

    Und es funktioniert (im onActivityCreated Callback).

    • Über die Cast-Ausnahme: Wie hierarchyviewer zeigt, ist der Baum so: Hierarchyviewer sc findViewById , wenn Sie findViewById übergeben Wurzel-Element der Ansicht, wie in diesem Post , wird es zurückgeben NoSaveStateFrameLayout , die nicht das Kind ListView Sie wollen.

    getActivity().findViewById() sucht nach der ID, die Sie als Parameter in der Hierarchie der Ansichten der Activity getActivity().findViewById() . Wahrscheinlich wird die ListView von onCreateView deines Fragments zurückgegeben. Wenn Sie eine findViewById auf der Fragmentansichtshierarchie durchführen findViewById , müssen Sie getView().findViewById() . In diesem Fall, da Sie ListFragment , um das ListView , wie für die ListActivity , müssen Sie getListView(); Eine weitere Analogie mit der ListActivity ist die ID der ListView in der XML-Datei ( android:id="@android:id/list" )

    Beachten Sie, dass ListFragment eine Methode getListView() , um die ListView Widget-Instanz zurückzugeben.

    Entwicklerdokumente: ListFragment.getListView

    @theme eine Lösung vorschlagen, aber um die innere Listenansicht von Android zu benutzen, ist hier ein anderer Weg. Denn in deiner "contact_list_view.xml" -Datei findest du die innere Listenansicht von Android mit id = @ android: id / list. Und in deinem Code kannst du auf die Listenansicht mit findViewById (android.R.id.list) verweisen, also dein onActivityCreated wird so sein:

     public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mContactsList = (ListView) getActivity().findViewById(android.R.id.list);//(R.layout.fragment_contact_list); mCursorAdapter = new SimpleCursorAdapter(getActivity(), R.layout.contact_item_list,null, FROM_COLUMNS, TO_IDS, 0); mContactsList.setAdapter(mCursorAdapter); mContactsList.setOnItemClickListener(this); getLoaderManager().initLoader(0,null,this); } 

    Hoffe es hilft, es ist gut die Android-Entwickler-Guide enthält solche "Bug", so dass wir mit der API vertraut sein können.

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.