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数据源未联动,以下是修复方案:
关键改动思路
- 用变量存储请求Future,避免重复发起API请求
- 数据请求完成后调用
setState更新userlist,触发组件重建 - 让
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
相关产品推荐
相关产品推荐

