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

Flutter中FutureBuilder列表子项经弹窗确认删除后如何刷新视图

问题原因

FutureBuilder 只会在所属 Widget 首次构建时执行一次传入的 future 异步任务,后续如果没有触发重构建、且future实例没有变更的话,不会重新执行接口请求拉取最新数据,因此删除操作完成后列表不会自动更新。


方案1:删除成功后重新拉取接口刷新列表

适合数据需要和服务端强一致的场景,操作步骤如下:

  1. 首先将你的页面改为 StatefulWidget,在 State 中定义变量存储 Future 实例,不要直接把 getAllInstructors() 写在 FutureBuilder 的 future 参数里
  2. 删除操作执行成功后,调用 setState 重新给 Future 变量赋值,触发 FutureBuilder 重执行拉取最新数据

示例代码:

class InstructorListPage extends StatefulWidget {
  const InstructorListPage({super.key});

  @override
  State<InstructorListPage> createState() => _InstructorListPageState();
}

class _InstructorListPageState extends State<InstructorListPage> {
  // 存储异步任务实例
  late Future<List<Instructor>> _instructorsFuture;

  @override
  void initState() {
    super.initState();
    _instructorsFuture = getAllInstructors();
  }

  // 封装删除逻辑
  Future<void> _deleteInstructor(int id) async {
    // 执行你的删除接口逻辑
    await deleteInstructor(id);
    // 删除成功后重新赋值Future,触发刷新
    setState(() {
      _instructorsFuture = getAllInstructors();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder<List<Instructor>>(
        // 绑定state中的future变量,不要直接写getAllInstructors()
        future: _instructorsFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          }
          if (snapshot.hasError) {
            return Center(child: Text('加载失败:${snapshot.error}'));
          }
          final instructors = snapshot.data!;
          return ListView.builder(
            itemCount: instructors.length,
            itemBuilder: (context, index) {
              final instructor = instructors[index];
              return InstructorItem(
                data: instructor,
                // 侧滑删除点击后的确认回调
                onDeleteConfirm: () => _deleteInstructor(instructor.id),
              );
            },
          );
        },
      ),
    );
  }
}

方案2:本地更新列表数据,无需二次请求接口

适合删除成功后可确定服务端数据已更新,不需要重复拉取的场景,性能更好:

  1. 拿到接口返回的数据后在 State 中缓存一份本地列表
  2. 删除成功后直接操作本地列表移除对应数据,再调用 setState 触发重绘即可

示例核心代码片段:

class _InstructorListPageState extends State<InstructorListPage> {
  List<Instructor> _instructors = [];
  bool _isLoading = true;
  String? _error;

  @override
  void initState() {
    super.initState();
    _loadData();
  }

  Future<void> _loadData() async {
    try {
      final data = await getAllInstructors();
      setState(() {
        _instructors = data;
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _error = e.toString();
        _isLoading = false;
      });
    }
  }

  Future<void> _deleteInstructor(int id) async {
    await deleteInstructor(id);
    // 直接移除本地列表中对应数据
    setState(() {
      _instructors.removeWhere((item) => item.id == id);
    });
  }

  @override
  Widget build(BuildContext context) {
    if (_isLoading) return const Center(child: CircularProgressIndicator());
    if (_error != null) return Center(child: Text('加载失败:$_error'));
    return ListView.builder(
      itemCount: _instructors.length,
      itemBuilder: (context, index) => InstructorItem(
        data: _instructors[index],
        onDeleteConfirm: () => _deleteInstructor(_instructors[index].id),
      ),
    );
  }
}

注意事项

  • 不要直接在 FutureBuilder 的 future 参数中写 future: getAllInstructors(),这种写法会导致每次 Widget 重构建时都重新执行接口请求,造成不必要的性能损耗
  • 删除操作执行前建议加 loading 状态,避免用户重复点击触发多次删除请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 06:36:02