4

나는 을 사용하여 기기의 앨범과 관련 아티스트의 목록을 표시 할 ListFragment입니다. 따라서 각 행에는 두 개의 TextViews이 있습니다. TextViews 행에 데이터를 바인딩하기 위해 LoaderManagerCursorLoader을 사용하여 목록을 채우고 사용자 지정 CursorAdapter를 사용하고 있습니다.LoaderManager 및 CursorLoader의 listview에 앨범과 아티스트를 표시합니다.

ListFragment 코드 :

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 (사용자 정의 CursorAdapter) 코드 :이 ListFragment를 표시 할 때 순간

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

, 나는 java.lang.NullPointerException이 있습니다 다음은 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) 

앨범 및 관련 아티스트를 목록보기에 표시하려면 코드 수정을 도와 주시겠습니까?

문제 해결 :

1) 자신의 사용자 정의 만들기 : 당신이해야하는 기술 LoaderManager/CursorLoader와 등 앨범, 아티스트와 사용자 지정 목록보기를 채우기 위해 시도하는 사람 ... 들어

당신의 조각에, 그리고 (위 단골 CursorAdapter 참조)

2) 커서의 데이터에 행의 TextViews을 결합 CursorAdapter 여기서해야 할 작업은 다음과 같습니다

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

그리고 그게 전부입니다 !!! 사용자 정의 목록보기를 채우기 위해 LoaderManager, CursorLoader 및 사용자 지정 어댑터를 사용하는 방법에 대해 이처럼 간단한 예제를 아무도 얻지 못한 이유가 무엇인지 모르겠습니다. 어쨌든이게 나 같은 미래 초보자들에게 도움이되기를 바랍니다.

+0

당신은 예외가있는 경우 ('NullPointerException' 또는 무엇이든 예외) 당신은 항상 줄 곳을 표시해야합니다 그 예외가 슬로우됩니다. – Luksprog

+0

@Luksprog : 정확성에 감사 드리며, 내 게시물을 업데이트했습니다. 예외는 'mAdapter.swapCursor (data);'가있는 61 행에있는 것처럼 보입니다. 어쩌면'MediaStore'에 질의하는 방식이 잘못되어 데이터가 비어있어이 예외가 생길 수 있습니다. – Jecimi

+0

안녕하세요. 제이미. 괜찮으 시다면 몇 가지 질문이 있습니다. LoaderManager 및 CursorLoader를 사용하여 CursorAdapter를 만들려고합니다. 나는 데이터베이스에서 커서를 얻고있다. ListFragment를 사용하지 않고 일반 목록 만 사용합니다. 즉, 내 목록은 실제로 다른보기 인 GridView에있는 활동에 있음을 의미합니다. 현재 레이아웃을 변경하지 않고 LoaderManager 및 CursorLoader를 사용하도록 어떻게 설정합니까? – Andy

답변

2

나는 mAdapternull이라고 생각합니다. 초기화 한 경우 초기화 된 곳이 보이지 않으며 커서를 교체하려고하면 예외가 발생합니다.

당신은 당신이 어댑터를 설정하기 전에 AlbumAdapter 참조 당신이 그것을 할 것을 초기화되지 않은 경우 :

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

두 가지가 누락되었습니다. 내가 말한대로 사용자 정의 어댑터를 초기화하는 것을 잊었으며 'MediaStore.Audio.Albums._ID'를 내 계획에 넣는 것을 잊었습니다. – Jecimi

관련 문제