繁体   English   中英

专辑封面可绘制未在ListView中显示[Android]

[英]Album Art Drawable Not Showing Up in ListView [Android]

我已经尝试了好几天了,但是似乎找不到解决方案。

问题在于,即使从MediaStore获取专辑封面位图并将其转换为可绘制对象之后,它仍通过HashMap(字符串,对象)分配给自定义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});
          }
    }
}

我检测到drawable可能是导致图片无法显示的原因,因为如果我替换-

item.put("icon", drawable);

与-

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

它显示了默认的专辑封面。

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

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

  • item.put("icon", drawable) -这将一个Drawable对象放到您的哈希图中

  • item.put("icon", R.drawable.default_albumart) -这会将int值添加到地图中,但是由于地图仅适用于对象,因此在放入之前会自动装箱

因此,问题在于您的适配器可以与drawable的整数标识符一起正常工作,而与drawable本身不兼容。 这些是SimpleAdapter的约束

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

随时在评论中提问,祝您好运!

答案是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);
}
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM