ListView.separated点击下载后所有尾部图标变进度指示器的修复方案
问题原因分析
你当前的核心问题有两个:
- 用了单个全局布尔值
isDownloading,所有列表项都绑定这个变量,所以只要触发一次setState,所有行都会同步切换成进度条。 - 下载逻辑是同步执行的——刚把
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,提问作者ඞඞඞ
相关产品推荐
相关产品推荐

