You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中QueryArtworkWidget播放歌曲时图片闪烁如何修复

Flutter on_audio_query 播放时封面闪烁修复方案

闪烁原因

realtimePlayingInfos 是高频刷新流,播放进度更新、状态回调都会触发其监听事件执行,直接在组件树中从该实例取歌曲ID传入QueryArtworkWidget会导致:

  1. 每次进度刷新都触发组件重建,即使歌曲ID没有变化
  2. QueryArtworkWidget 默认未开启旧封面保留逻辑,新封面加载过程中会先显示空白占位再切到封面,造成视觉上的闪烁
  3. 未指定封面解码尺寸时,每次重建都会重新读取原图解码,IO和解码开销大,进一步加剧闪烁

修复步骤

  • 拦截无意义重建:不要直接在build方法里从realtimePlayingInfos取歌曲ID,单独维护一个currentPlayingId状态,仅在监听到播放歌曲ID真正发生变化(切歌)时才更新该状态,进度更新、播放状态变化这类不涉及歌曲切换的场景不触发封面组件重建
  • 开启QueryArtworkWidget旧封面保活:添加keepOldArtwork: true参数,新封面加载完成前始终保留上一帧已显示的封面,不会出现空白跳变
  • 指定固定封面解码、缓存尺寸:根据组件实际展示大小设置artworkWidth、artworkHeight以及对应缓存尺寸,避免每次重建都读取全尺寸原图解码,减少IO开销
  • 固定解码格式:明确指定format参数,避免系统每次自动选择解码格式导致的重绘差异

修复后参考代码

// 状态类中维护当前播放歌曲ID,初始值可设为null
int? currentPlayingId;

@override
void initState() {
  super.initState();
  // 监听播放信息流,仅在切歌时更新封面ID
  audioPlayer.playingInfoStream.listen((infos) {
    final newId = int.tryParse(infos.current?.audio.audio.metas.id ?? '');
    if (newId != null && newId != currentPlayingId) {
      setState(() {
        currentPlayingId = newId;
      });
    }
  });
}

@override
Widget build(BuildContext context) {
  // 封面组件
  return ClipRRect(
    borderRadius: BorderRadius.circular(10),
    child: currentPlayingId == null 
      ? Icon(
          Icons.music_note,
          color: Colors.white,
          size: 40,
        )
      : QueryArtworkWidget(
          keepOldArtwork: true,
          artworkWidth: 80, // 替换为你实际需要的封面宽度
          artworkHeight: 80, // 替换为你实际需要的封面高度
          artworkCacheWidth: (80 * MediaQuery.of(context).devicePixelRatio).round(),
          artworkCacheHeight: (80 * MediaQuery.of(context).devicePixelRatio).round(),
          format: ArtworkFormat.JPEG,
          nullArtworkWidget: Icon(
            Icons.music_note,
            color: Colors.white,
            size: 40,
          ),
          id: currentPlayingId!,
          type: ArtworkType.AUDIO,
        ),
  );
}

注意:如果项目中使用了状态管理(Provider、Bloc、Riverpod等),可以将当前播放ID放到对应状态中管理,核心逻辑不变:只有切歌时才更新封面组件依赖的ID值。

内容的提问来源于stack exchange,提问作者Rohit Krishna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 22:45:45