【问题标题】:Album Art Drawable Not Showing Up in ListView [Android]专辑封面 Drawable 未显示在 ListView [Android] 中
【发布时间】:2014-04-20 17:56:35
【问题描述】:

这几天我一直在尝试解决这个问题,但似乎找不到解决方案。

问题是即使在从 MediaStore 获取专辑封面位图并将其转换为可绘制对象后,仍会通过 HashMap (String, Object) 将其分配给自定义 ListView 布局中的 ImageView,但最终在实际设备和模拟器上运行后,没有显示专辑封面。

也没有 LogCat 错误。自定义列表视图布局的 ImageView 不显示专辑封面。

public class AllSongs extends Fragment
{ 
Bitmap bitmap = null;
BitmapDrawable drawable = null; 
private ArrayList<HashMap<String,Object>> list = new ArrayList<HashMap<String,Object>>();
private HashMap<String, Object> item;
private SimpleAdapter sa;
private ListView listview;
 ... 
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
...
AsyncTaskRunner runner = new AsyncTaskRunner();
runner.execute("500");
}
private class AsyncTaskRunner extends AsyncTask<String, String, String>
    {

    @Override
    protected String doInBackground(String... params) {
        getAllMusicFiles();
        return "Done!";
    }
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        listview.setAdapter(sa); //Set all the file in the list.
    }
    }
private void getAllMusicFiles() {
    // TODO Auto-generated method stub
    //Some audio may be explicitly marked as not being music
    String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";

    String[] projection = {
        MediaStore.Audio.Media.TITLE,
        MediaStore.Audio.Media.ARTIST,
        MediaStore.Audio.Media.ALBUM,
        MediaStore.Audio.Media.ALBUM_ID
    };
    Cursor cursor = getActivity().getApplicationContext().getContentResolver().query(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        projection,
        selection,
        null,
        null);
    while(cursor.moveToNext()){
          item = new HashMap<String,Object>();
          String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
          String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
          String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
          long albumId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));

          final Uri ART_CONTENT_URI = Uri.parse("content://media/external/audio/albumart");
            Uri albumArtUri = ContentUris.withAppendedId(ART_CONTENT_URI, albumId);
            ContentResolver res = context.getContentResolver();
              InputStream in;
                try { // Yes, the album art has been found. I am sure of this.
                    if(bitmap != null)
                    {
                        bitmap.recycle();
                        bitmap = null;
                        if(drawable != null)
                        {
                            drawable = null;
                        }
                    }
                    in = res.openInputStream(albumArtUri);
                    bitmap = BitmapFactory.decodeStream(in);
                    drawable = new BitmapDrawable(getResources(), bitmap);
                } catch (FileNotFoundException e) { // Album not found so set default album art
                    e.printStackTrace();
                    drawable = (BitmapDrawable) getActivity().getResources().getDrawable(R.drawable.default_albumart);
                }
          item.put("icon", drawable);
          item.put("title", title);
          item.put("artist", artist);
          list.add(item);
          if(cursor.isLast())
          {
             sa = new SimpleAdapter(getActivity(), list,
             R.layout.custom_listview_layout,
                new String[] {"icon", "title","artist" },
                new int[] {R.id.icon,R.id.title, R.id.artist});
          }
    }
}

我检测到可绘制对象可能是导致图像无法显示的原因,因为如果我替换 -

item.put("icon", drawable);

与 -

item.put("icon", R.drawable.default_albumart);

它显示默认专辑封面。

知道是什么原因造成的吗?

【问题讨论】:

    标签: android android-listview android-drawable mediastore


    【解决方案1】:

    是您的适配器实现导致了问题,而不是 Drawable。 看这两行代码:

    • item.put("icon", drawable) - 这会将一个 Drawable 对象放到你的 hashmap 中

    • item.put("icon", R.drawable.default_albumart) - 这会将 int 值添加到您的地图中,但由于地图仅适用于对象,因此在被放置之前它是 autoboxed

    因此,问题在于您的适配器适用于可绘制对象的整数标识符,但不适用于可绘制对象本身。这些是SimpleAdapter的约束

    要解决此问题,我建议您实现自定义 CursorAdapter。它的实现非常简单,并且可以让您免于不必要的步骤,例如创建不必要的列表、哈希图等,浪费应用程序内存。

    请随时在 cmets 中提出任何其他问题,祝您好运!

    【讨论】:

    • 没错!我还添加了我如何实现这一点的答案(还有一些其他问题),其中包括任何想知道它是如何完成的新手的代码。太好了!
    【解决方案2】:

    Drew 给出了正确的答案,但这是最终实施的方式。以下是更改 -

    private void getAllMusicFiles() {
        // TODO Auto-generated method stub
        //Some audio may be explicitly marked as not being music
        String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
    
        String[] projection = {
            MediaStore.Audio.Media._ID, // this is required acc to documentation
            MediaStore.Audio.Media.TITLE,
            MediaStore.Audio.Media.ARTIST,
            MediaStore.Audio.Media.ALBUM,
            MediaStore.Audio.Media.ALBUM_ID
        };
        cursor = getActivity().getApplicationContext().getContentResolver().query(
            MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            projection,
            selection,
            null,
            null);
        getActivity().startManagingCursor(cursor);
        listview.setAdapter(new CustomCursorAdapter(context, cursor));
    }
    
    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        if(cursor != null)
        {
        getActivity().stopManagingCursor(cursor);
        cursor.close();
        }
        super.onDestroy();
    }
    

    删除了 AsyncTask,因为这里不再需要它。

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState)
    {
    ...
    AsyncTaskRunner runner = new AsyncTaskRunner();
    runner.execute("500");
    }
    



    CustomCursorAdapter.java -

    public class CustomCursorAdapter extends CursorAdapter {
    @SuppressWarnings("deprecation")
    public CustomCursorAdapter(Context context, Cursor c) {
        super(context, c);
        // TODO Auto-generated constructor stub
    }
    
    private Bitmap bitmap = null;
    private BitmapDrawable drawable = null;
    
    
    
    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        // TODO Auto-generated method stub
        TextView title1 = (TextView) view.findViewById(R.id.title);
        TextView artist1 = (TextView) view.findViewById(R.id.artist);
        ImageView album1 = (ImageView) view.findViewById(R.id.icon);
    
        String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
        String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
        String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
        long albumId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
          StringBuilder titleBuild = new StringBuilder();
          titleBuild.append(title);
          if(titleBuild.length() > 35)
          {
          titleBuild.setLength(32);
          title = titleBuild.toString()+"...";
          }
          else
          {
              title = titleBuild.toString();
          }
          StringBuilder artistBuild = new StringBuilder();
          artistBuild.append(artist);
          if(artistBuild.length() > 35)
          {
          artistBuild.setLength(32);
          artist = artistBuild.toString()+"...";
          }
          else
          {
          artist = artistBuild.toString();
          }
    
          final Uri ART_CONTENT_URI = Uri.parse("content://media/external/audio/albumart");
            Uri albumArtUri = ContentUris.withAppendedId(ART_CONTENT_URI, albumId);
            ContentResolver res = context.getContentResolver();
              InputStream in;
                try {
                    if(bitmap != null)
                    {
                        bitmap = null;
                        if(drawable != null)
                        {
                            drawable = null;
                        }
                    }
                    in = res.openInputStream(albumArtUri);
                    bitmap = BitmapFactory.decodeStream(in);
                    // bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), albumArtUri);
                    drawable = new BitmapDrawable(context.getResources(), bitmap);
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    drawable = (BitmapDrawable) context.getResources().getDrawable(R.drawable.default_albumart);
                }
    album1.setImageDrawable(drawable);
    title1.setText(title);
    artist1.setText(artist);
    }
    
    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        // TODO Auto-generated method stub
        LayoutInflater inflater = (LayoutInflater)context.getSystemService
                  (Context.LAYOUT_INFLATER_SERVICE);
        return inflater.inflate(R.layout.custom_listview_layout, parent, false);
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-02
      相关资源
      最近更新 更多