I am following the contacts provider lesson on retrieving contacts and displaying them using fragments. For reference, I have set the API level to 16 (Android 4.1).
I have mostly followed this tutorial to the letter, with a few notable exceptions. For example, I import from mypackage.R
rather than android.R
.
My problem is in my onActivityCreated
handler in my 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
is null, meaning findViewById
didn't work.
My parent activity is a default one created by eclipse. To this, I have done two things:
- Replaced
import android.app.Activity
withandroid.support.v4.app.FragmentActivity
to prevent theClasscastException
that happens if you don't. - Imported my fragment into the XML.
My activity_list_contacts.xml
looks like this:
<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>
the matching activity, just in case:
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;
}
}
and 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"/>
So my question is, what am I doing wrong for findViewById
not to find my view?
Things I have tried (most of these are accepted answers on questions that almost look like a duplicate to this one):
- Reading the document I copied and pasted from word for word.
- Trying to
getView().findViewById()
as suggested in this question. This also returns null. - using
findViewById(R.id.contacts_list_view);
instead as suggested by this answer. This doesn't return null; instead it causes aClassCastException
in thatandroid.support.v4.app.NoSaveStateFrameLayout
could not be cast toandroid.widget.ListView
. I read that sometimes the fragment callback for creation occurs before being attached to the activity. So, I added the handler to the
onAttach
method like so:@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); }
You guessed it - still null.
So at this point I am a little lost. I have two questions:
- What am I doing wrong (please request additional info in comments if I have not provided enough)?
- Is it preferable to leave the adapter setup in
onAttach
, or where the tutorial says.