getActivity().findViewById renvoie la valeur null, appelé à partir de fragment onActivityCreated

Je suis à la suite de la contacts fournisseur de leçon sur la récupération des contacts et de les afficher à l'aide de fragments. Pour référence, j'ai mis de l'API de niveau 16 (Android 4.1).

J'ai surtout suivi ce tutoriel à la lettre, avec quelques exceptions notables. Par exemple, je l'importation de mypackage.R plutôt que android.R.

Mon problème est que dans mon onActivityCreated gestionnaire dans mon 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 est null, sens findViewById n'a pas fonctionné.

Mon activité parent est un par défaut créé par eclipse. Pour cela, j'ai fait deux choses:

  1. Remplacé import android.app.Activity avec android.support.v4.app.FragmentActivity pour empêcher la ClasscastException qu'advient-il si vous ne le faites pas.
  2. Importé mon fragment dans le XML.

Mon activity_list_contacts.xml ressemble à ceci:

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

l'activité d'appariement, juste au cas où:

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;
    }
}

et 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"/>

Donc ma question est, ce que je fais mal pour findViewById de ne pas trouver mon point de vue?

Choses que j'ai essayé (la plupart de ces sont acceptés réponses sur des questions qui ressemblent presque à un doublon de celui-ci):

  • La lecture du document, je l'ai copié et collé à partir de word pour word.
  • Essayer de getView().findViewById() comme l'a suggéré dans cette question. Cela renvoie également la valeur null.
  • à l'aide de findViewById(R.id.contacts_list_view); plutôt comme suggéré par cette réponse. Ce n'est pas return null; au lieu de cela, il provoque une ClassCastException dans ce android.support.v4.app.NoSaveStateFrameLayout ne peut pas être converti à android.widget.ListView.
  • J'ai lu que parfois le fragment de rappel pour la création se produit avant d'être affecté à l'activité. Donc, j'ai ajouté le gestionnaire de la onAttach méthode comme suit:
    @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);
    }

    Vous l'aurez deviné - toujours null.

De sorte à ce point, je suis un peu perdu. J'ai deux questions:

  1. Ce que je fais mal (merci de demander un complément d'info dans les commentaires si je n'ai pas donné assez)?
  2. Est-il préférable de laisser la configuration de l'adaptateur dans onAttach, ou lorsque le tutoriel dit.
Si vous utilisez un id à partir de l'Android, elle devrait être utilisée comme android.R.id.*. Est TO_IDS défini comme private final static int[] TO_IDS = { android.R.id.text1 }?
yep, il est, en tant que membre du fragment de la classe.

OriginalL'auteur | 2013-08-01