Display album and artist in a list using LoaderManager and CursorLoader

I have a ListFragment , in the list of which the Albums of the device and the associated artist should be displayed using the MediaStore . Thus, each row has two TextViews . I use LoaderManager and CursorLoader to populate the list up, using a special CursorAdapter to bind TextViews to a string to data.

List Code:

 public class AlbumsFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> { AlbumsAdapter mAdapter; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View myFragmentView = inflater.inflate(R.layout.albums_fragment_layout, container, false); return myFragmentView; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setListAdapter(mAdapter); getLoaderManager().initLoader(0, null, this); } static final String[] ALBUM_SUMMARY_PROJECTION = { MediaStore.Audio.Albums.ALBUM, MediaStore.Audio.Albums.ARTIST}; public Loader<Cursor> onCreateLoader(int id, Bundle args) { String select = null; return new CursorLoader(getActivity(), MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,ALBUM_SUMMARY_PROJECTION, select, null, null); } public void onLoadFinished(Loader<Cursor> loader, Cursor data) { mAdapter.swapCursor(data); } public void onLoaderReset(Loader<Cursor> loader) { mAdapter.swapCursor(null); } } 

AlbumsAdapter (Custom CursorAdapter) Code:

 public class AlbumsAdapter extends CursorAdapter { private final LayoutInflater mInflater; public AlbumsAdapter(Context context, Cursor c) { super(context, c); mInflater=LayoutInflater.from(context); } @Override public void bindView(View view, Context context, Cursor cursor) { TextView albumTitle =(TextView)view.findViewById(R.id.albumTextView); albumTitle.setText(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM))); TextView artistName=(TextView)view.findViewById(R.id.artistTextView); artistName.setText(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Albums.ARTIST))); } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { final View view=mInflater.inflate(R.layout.albums_row,parent,false); return view; } 

At the moment, when I show this ListFragment, I have java.lang.NullPointerException, here is logCat:

  06-14 09:39:23.109: W/dalvikvm(8632): threadid=1: thread exiting with uncaught exception (group=0x40c2d1f8) 06-14 09:39:23.109: E/AndroidRuntime(8632): FATAL EXCEPTION: main 06-14 09:39:23.109: E/AndroidRuntime(8632): java.lang.NullPointerException 06-14 09:39:23.109: E/AndroidRuntime(8632): at com.music.pod.AlbumsFragment.onLoadFinished(AlbumsFragment.java:61) 06-14 09:39:23.109: E/AndroidRuntime(8632): at com.music.pod.AlbumsFragment.onLoadFinished(AlbumsFragment.java:1) 06-14 09:39:23.109: E/AndroidRuntime(8632): at android.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:438) 06-14 09:39:23.109: E/AndroidRuntime(8632): at android.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:406) 06-14 09:39:23.109: E/AndroidRuntime(8632): at android.content.Loader.deliverResult(Loader.java:125) 06-14 09:39:23.109: E/AndroidRuntime(8632): at android.content.CursorLoader.deliverResult(CursorLoader.java:88) 06-14 09:39:23.109: E/AndroidRuntime(8632): at android.content.CursorLoader.deliverResult(CursorLoader.java:42) 06-14 09:39:23.109: E/AndroidRuntime(8632): at android.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:236) 06-14 09:39:23.109: E/AndroidRuntime(8632): at android.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:76) 06-14 09:39:23.109: E/AndroidRuntime(8632): at android.os.AsyncTask.finish(AsyncTask.java:602) 06-14 09:39:23.109: E/AndroidRuntime(8632): at android.os.AsyncTask.access$600(AsyncTask.java:156) 06-14 09:39:23.109: E/AndroidRuntime(8632): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615) 06-14 09:39:23.109: E/AndroidRuntime(8632): at android.os.Handler.dispatchMessage(Handler.java:99) 06-14 09:39:23.109: E/AndroidRuntime(8632): at android.os.Looper.loop(Looper.java:137) 06-14 09:39:23.109: E/AndroidRuntime(8632): at android.app.ActivityThread.main(ActivityThread.java:4507) 06-14 09:39:23.109: E/AndroidRuntime(8632): at java.lang.reflect.Method.invokeNative(Native Method) 06-14 09:39:23.109: E/AndroidRuntime(8632): at java.lang.reflect.Method.invoke(Method.java:511) 06-14 09:39:23.109: E/AndroidRuntime(8632): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790) 06-14 09:39:23.109: E/AndroidRuntime(8632): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557) 06-14 09:39:23.109: E/AndroidRuntime(8632): at dalvik.system.NativeStart.main(Native Method) 

Could you help me correct my code so that the album and the artist associated with it appear in the list?

Problem resolved:

For those trying to populate a custom listview with Album, Artist, etc. using the LoaderManager / CursorLoader method, you must:

1) Create your own custom CursorAdapter that associates the TextViews of your string with cursor data (see my custom CursorAdapter above)

2) Then in your fragment here what to do:

 public class AlbumsFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> { AlbumsAdapter mAdapter; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View myFragmentView = inflater.inflate(R.layout.albums_fragment_layout, container, false); return myFragmentView; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mAdapter = new AlbumsAdapter(getActivity(), null); setListAdapter(mAdapter); getLoaderManager().initLoader(0, null, this); } static final String[] ALBUM_SUMMARY_PROJECTION = { MediaStore.Audio.Albums._ID, MediaStore.Audio.Albums.ALBUM, MediaStore.Audio.Albums.ARTIST}; public Loader<Cursor> onCreateLoader(int id, Bundle args) { String select = null; return new CursorLoader(getActivity(), MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,ALBUM_SUMMARY_PROJECTION, select, null, null); } public void onLoadFinished(Loader<Cursor> loader, Cursor data) { mAdapter.swapCursor(data); } public void onLoaderReset(Loader<Cursor> loader) { mAdapter.swapCursor(null); } } 

What is it!!! I donโ€™t know why no one has ever purchased such a simple example, how to use LoaderManager, CursorLoader and Custom adapter to populate a custom list. In any case, I hope this helps newcomers, like me, in the future.

+4
source share
1 answer

I think your mAdapter is null (I donโ€™t see where you initialized it if you initialized it), and when you try to change the cursor, it throws this exception.

if you did not initialize this AlbumAdapter link, then you must do this before installing the adapter:

 mAdapter = new AlbumsAdapter(getActivity(), null); setListAdapter(mAdapter); 
+2
source

All Articles