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

Flutter中ListTile图标无法实时更新问题求助

Flutter ListTile播放图标无法实时切换问题

问题现象

  • 点击同一个ListTile的播放/暂停图标时,图标无任何变化
  • 只有点击其他ListTile的图标时,之前的图标才会更新为正确状态

问题代码

import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';

class MusicPlayerController extends ChangeNotifier {
  final player = AudioPlayer();
  int _playingIndex = -1;

  MusicPlayerController() {
    player.playerStateStream.listen((state) {
      if (state.processingState == ProcessingState.completed) {
        _playingIndex +=1;
        notifyListeners();
      }
    });
  }

  Future<void> playOrPause(int index, String uri) async {
    if (index == _playingIndex) {
      if (player.playing){
        player.stop();
        icon(index);
      } else{
        player.play();
      }
      notifyListeners(); // 新增这行解决了问题
    } else {
      player.setAudioSource(AudioSource.uri(Uri.parse(uri)));
      player.play();
      _playingIndex = index;
      notifyListeners();
    }
  }

  Icon icon(int index) {
    if (index == _playingIndex) {
      return player.playing ? Icon(Icons.pause_circle) : Icon(Icons.play_circle_outline_outlined) ;
    } else {
      return Icon(Icons.play_circle_outline_outlined);
    }
  }
}

// ListTile部分代码
return ListTile(
  // title、subtitle、leading 省略
  trailing:Consumer<MusicPlayerController>(
    builder: (context, controller, child) {
      return IconButton(
        iconSize: 30,
        onPressed: () {
          controller.playOrPause(index,(provider.musicList[index].uri).toString());
        },
        icon: controller.icon(index),
      );
    },
  )
);

问题原因与解决方案

核心原因
当点击同一行的图标切换播放状态时,player.playing的值已经改变,但没有调用notifyListeners()通知Consumer重新构建UI,导致图标无法实时更新。

修复方案
在index == _playingIndex的分支末尾添加notifyListeners(),确保每次播放状态变化时,都能触发UI更新。

优化建议
可以直接监听player.playing的变化,自动触发通知,避免手动调用遗漏:

MusicPlayerController() {
  // 监听播放完成事件
  player.playerStateStream.listen((state) {
    if (state.processingState == ProcessingState.completed) {
      _playingIndex +=1;
      notifyListeners();
    }
  });
  // 监听播放状态变化,自动通知UI
  player.playingStream.listen((playing) {
    notifyListeners();
  });
}

这样修改后,playOrPause方法中可以去掉手动调用的notifyListeners(),让状态变更的通知更自动化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 09:07:09