求助:RecyclerView中专辑封面不显示,如何加载本地歌曲列表及封面?
解决RecyclerView中专辑封面无法显示的问题
嘿,看来你已经搞定了歌曲列表的获取,卡在专辑封面这一步了对吧?别担心,我来一步步帮你解决这个问题:
1. 生成专辑封面的内容Uri
你已经在Cursor里拿到了MediaStore.Audio.Media.ALBUM_ID,接下来可以通过这个ID直接生成专辑封面的内容Uri,Android的MediaStore提供了现成的API来做这件事:
private Uri getAlbumCoverUri(long albumId) { // 基于专辑ID构建封面的Content Uri return ContentUris.withAppendedId( MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, albumId ); }
注意:部分歌曲可能没有关联专辑或专辑本身无封面,记得准备一张默认占位图避免显示空白。
2. 在RecyclerView Adapter中异步加载封面
直接用原生BitmapFactory加载图片容易触发内存溢出(OOM),还会阻塞UI线程,强烈推荐用成熟的图片加载库,这里以Glide为例:
首先在Module级别的build.gradle添加依赖:
implementation 'com.github.bumptech.glide:glide:4.16.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
然后在ViewHolder的绑定方法中加载封面:
// 假设你的ViewHolder里有一个ImageView用于展示封面:albumCoverIv // song是你的歌曲数据模型,包含albumId字段 Uri coverUri = getAlbumCoverUri(song.getAlbumId()); Glide.with(itemView.getContext()) .load(coverUri) .placeholder(R.drawable.default_album_cover) // 加载中占位图 .error(R.drawable.default_album_cover) // 无封面/加载失败时显示的图 .centerCrop() // 适配ImageView尺寸 .into(albumCoverIv);
3. 权限适配(必做!)
不同Android版本的媒体文件访问权限要求不同:
- Android 10(API 29)及以下:需要
READ_EXTERNAL_STORAGE权限 - Android 13+:需要
READ_MEDIA_AUDIO权限
在AndroidManifest.xml中声明权限:
<!-- Android 10及以下适配 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="29" /> <!-- Android 13+适配 --> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
记得在运行时动态申请对应权限,否则无法读取媒体文件信息。
4. 特殊情况:无封面专辑的兜底处理
如果部分专辑通过Uri仍无法加载封面,可以尝试直接读取专辑封面的文件路径:
// 先扩展你的cursor_cols,新增ALBUM_ART字段 final String[] cursor_cols = { MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.ALBUM_ID, MediaStore.Audio.Media.DURATION, MediaStore.Audio.Media.ALBUM_ART // 新增封面路径字段 }; // 解析Cursor时获取封面路径 String albumArtPath = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ART)); if (albumArtPath != null && !albumArtPath.isEmpty()) { Glide.with(context).load(new File(albumArtPath)).into(albumCoverIv); } else { // 显示默认占位图 Glide.with(context).load(R.drawable.default_album_cover).into(albumCoverIv); }
最后检查点
- 确认歌曲数据模型正确保存了
ALBUM_ID或ALBUM_ART字段 - 确认权限已成功申请并授予
- 确认默认占位图资源存在于drawable目录中
这样处理后,你的RecyclerView应该就能正常显示专辑封面啦!
内容的提问来源于stack exchange,提问作者Ashuthosh Patoa
相关产品推荐
相关产品推荐

