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

ListView.separated点击下载后所有尾部图标变进度指示器的修复方案

问题原因分析

你当前的核心问题有两个:

  1. 用了单个全局布尔值isDownloading,所有列表项都绑定这个变量,所以只要触发一次setState,所有行都会同步切换成进度条。
  2. 下载逻辑是同步执行的——刚把isDownloading设为true,立刻又设回false,进度条根本来不及显示就被切换回去了。
修复方案

把单个布尔值换成集合来记录正在下载的行索引,同时将下载操作改为异步处理,确保UI能正确反映单一行的下载状态。

步骤1:替换状态变量

将原来的bool isDownloading = false;替换为集合,用来存储正在下载的行索引:

Set<int> _downloadingIndexes = {};

步骤2:修改列表项的trailing逻辑

根据当前行的index是否在下载集合中,决定显示下载按钮还是进度条:

ListView.separated(
  itemBuilder: (context, index) {
    final file = files[index];
    return ListTile(
      title: Text(file.name),
      subtitle: const Text(
        '123456789',
        style: TextStyle(
            fontFamily: 'Poppins',
            fontSize: 12,
            color: Colors.black),
      ),
      trailing: _downloadingIndexes.contains(index)
          ? const CircularProgressIndicator()
          : IconButton(
              icon: const Icon(Icons.download_rounded),
              onPressed: () async {
                // 将当前索引加入下载集合,触发UI更新显示进度条
                setState(() {
                  _downloadingIndexes.add(index);
                });
                // 异步执行下载操作,等待完成
                await downloadFile(index, file);
                // 下载完成后移除索引,恢复显示下载按钮
                setState(() {
                  _downloadingIndexes.remove(index);
                });
              },
            ),
    );
  },
  separatorBuilder: (_, index) => const SizedBox(height: 15),
  itemCount: files.length,
);

步骤3:确保下载方法是异步的

如果你的downloadFile目前是同步方法,需要改成返回Future,避免阻塞UI线程:

Future<void> downloadFile(int index, dynamic file) async {
  // 这里替换成你的实际下载逻辑,比如网络请求、文件写入等
  // 模拟下载延迟示例
  await Future.delayed(const Duration(seconds: 2));
  // 下载完成后的后续操作
}
效果说明

这样修改后,只有被点击的那一行会显示进度条,其他行保持下载按钮状态;下载完成后,该行自动恢复为下载按钮,完全符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 01:38:24