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

Flutter中使用FutureBuilder更新AppBar记录数问题求助

问题描述

我为学习FutureBuilder创建了一个演示项目,Scaffold主体通过API加载并展示所有用户,需在AppBar中显示用户总数,但AppBar加载后标题一直显示0且不会更新,请问该如何重建以更新数值?

用户提供的代码:

class _withmodelState extends State<withmodel> {

  List<UserModel> userlist=[];

  Future<List<UserModel>> getdata() async {
    final resp =
        await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));

    if (resp.statusCode == 200) {
      print('i ma called');
      List<dynamic> dlist = json.decode(resp.body);
      await Future.delayed(Duration(seconds: 2));

      userlist= dlist.map((e) => UserModel.fromJson(e)).toList();
      return userlist;
    }
    return userlist;
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
        child: Scaffold(
          appBar: AppBar(title: Text("Total users="+userlist.length.toString()),),
      body: MyBody(
        //MyBody returning FutureBuilder for showing userlist array;
      ),
    ));
  }
}
解决方案

核心问题是直接修改userlist后没有触发State重建,导致AppBar标题无法更新;同时当前代码中MyBody的FutureBuilder与父组件userlist数据源未联动,以下是修复方案:

关键改动思路

  1. 用变量存储请求Future,避免重复发起API请求
  2. 数据请求完成后调用setState更新userlist,触发组件重建
  3. 让MyBody的FutureBuilder复用同一个请求Future,保证数据源一致性

修改后的完整代码

class _withmodelState extends State<withmodel> {
  List<UserModel> userlist = [];
  // 存储请求Future,防止build重复触发请求
  late Future<List<UserModel>> _fetchUsersFuture;

  Future<List<UserModel>> getdata() async {
    final resp = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));

    if (resp.statusCode == 200) {
      List<dynamic> dlist = json.decode(resp.body);
      await Future.delayed(const Duration(seconds: 2));
      return dlist.map((e) => UserModel.fromJson(e)).toList();
    }
    return [];
  }

  @override
  void initState() {
    super.initState();
    // 初始化时发起请求,请求完成后更新状态
    _fetchUsersFuture = getdata().then((users) {
      setState(() {
        userlist = users;
      });
      return users;
    });
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(title: Text("Total users=${userlist.length}")),
        // 将请求Future传递给MyBody
        body: MyBody(fetchFuture: _fetchUsersFuture),
      ),
    );
  }
}

// 对应的MyBody组件实现
class MyBody extends StatelessWidget {
  final Future<List<UserModel>> fetchFuture;

  const MyBody({super.key, required this.fetchFuture});

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<UserModel>>(
      future: fetchFuture,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(child: CircularProgressIndicator());
        } else if (snapshot.hasError) {
          return Center(child: Text('加载失败:${snapshot.error}'));
        } else if (snapshot.hasData) {
          return ListView.builder(
            itemCount: snapshot.data!.length,
            itemBuilder: (context, index) {
              return ListTile(title: Text(snapshot.data![index].name));
            },
          );
        } else {
          return const Center(child: Text('暂无数据'));
        }
      },
    );
  }
}

方案说明

  • _fetchUsersFuture的作用:存储请求的Future对象,避免每次build方法执行时重复发起API请求
  • setState更新:请求完成后调用setState触发State重建,AppBar会重新读取userlist.length并更新标题
  • 共享数据源:父组件和MyBody使用同一个请求Future,保证两者数据同步,不会出现数据不一致的情况

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 09:40:31