title: Display Album and Artist in listview with LoaderManager and CursorLoader
body: <p>I have a <code>ListFragment</code> whose list should diplay the Albums of the device and the associated artist using <code>MediaStore</code>. Each row has thus two <code>TextViews</code>.
  I'm using <code>LoaderManager</code> and <code>CursorLoader</code> to fill the list up, with a custom CursorAdapter in order to bind the <code>TextViews</code> of the row to the data.</p>
  
  <p><strong>ListFragment Code :</strong></p>
  
  <pre><code>public class AlbumsFragment extends ListFragment implements LoaderManager.LoaderCallbacks&lt;Cursor&gt; {
  
  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&lt;Cursor&gt; 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&lt;Cursor&gt; loader, Cursor data) {  
              mAdapter.swapCursor(data);  
          }  
  
  
  
          public void onLoaderReset(Loader&lt;Cursor&gt; loader) {  
              mAdapter.swapCursor(null);  
          }  
      }
  </code></pre>
  
  <p><strong>AlbumsAdapter (Custom CursorAdapter) Code :</strong></p>
  
  <pre><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;
      }
  </code></pre>
  
  <p>For the moment, when I display this ListFragment, I have a java.lang.NullPointerException, here is the logCat :</p>
  
  <pre><code> 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)
  </code></pre>
  
  <p>Could you please help me to correct my code in order to have the album and the associated artist displayed into the listview ?</p>
  
  <p><strong>Problem Solved :</strong></p>
  
  <p>For anyone trying to fill up a custom listview with Album,Artist,etc... with the technique LoaderManager/CursorLoader you should :</p>
  
  <p>1) Create your own Custom CursorAdapter which binds TextViews of your row to Cursor's data(see my Custom CursorAdapter above)</p>
  
  <p>2) Then, in your fragment here's what to do :</p>
  
  <pre><code>public class AlbumsFragment extends ListFragment implements LoaderManager.LoaderCallbacks&lt;Cursor&gt; {
  
  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&lt;Cursor&gt; 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&lt;Cursor&gt; loader, Cursor data) {  
              mAdapter.swapCursor(data);  
          }  
  
  
  
          public void onLoaderReset(Loader&lt;Cursor&gt; loader) {  
              mAdapter.swapCursor(null);  
          }  
      }
  </code></pre>
  
  <p>And that's it !!! I don't know why nobody has ever procured a very simple example like this about how to use LoaderManager,CursorLoader and Custom adapter in order to fill a custom listview. Anyway, I hope this will help beginners like me in the future.</p>