Flutter:点击子页面按钮后如何实时更新AppBar中的余额数值?
解决Flutter中AppBar余额无法实时更新的问题
问题根源
你当前的代码里,UserInfos.money是静态变量,Page1中的setState()只会触发自身UI重建,HomePage的State完全感知不到money的变化,所以只有当HomePage被迫重建(切换页面、热重载)时,AppBar标题才会更新。
解决方案
方案一:回调函数传递更新事件(简单场景首选)
不需要额外依赖,通过回调让HomePage感知余额变化并触发自身重建:
- 修改Page1组件,添加回调参数:
class Page1 extends StatefulWidget { final VoidCallback onMoneyChanged; // 定义回调函数 const Page1({super.key, required this.onMoneyChanged}); @override State<Page1> createState() => _Page1State(); } class _Page1State extends State<Page1> { @override Widget build(BuildContext context) { return Center( child: ElevatedButton( onPressed: () { UserInfos.money -= 1; widget.onMoneyChanged(); // 点击后通知HomePage更新 }, child: const Text('decrease money')), ); } }
- 修改HomePage,传递回调触发自身
setState():
class _HomePageState extends State<HomePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(UserInfos.money.toString())), body: PageView( children: [ // 传递回调,触发HomePage重建 Page1(onMoneyChanged: () => setState(() {})), Page2(), ], ), ); } }
方案二:ChangeNotifier状态管理(适合复杂场景)
如果后续需要管理更多用户状态,推荐用Flutter自带的ChangeNotifier实现状态自动通知:
- 重构UserInfos为ChangeNotifier类:
import 'package:flutter/foundation.dart'; class UserInfos extends ChangeNotifier { int _money = 25000; // 对外暴露只读的money属性 int get money => _money; // 封装修改方法,内部通知状态变化 void decreaseMoney() { _money -= 1; notifyListeners(); } // 其他状态操作方法... }
- 在应用入口提供UserInfos实例:
void main() { runApp( ChangeNotifierProvider( create: (context) => UserInfos(), child: const MyApp(), ), ); }
注意:需先在
pubspec.yaml添加依赖:provider: ^6.0.5(版本号以最新为准)
- 修改HomePage,用Consumer监听状态变化:
class _HomePageState extends State<HomePage> { @override Widget build(BuildContext context) { return Scaffold( // Consumer自动监听UserInfos变化,更新AppBar appBar: Consumer<UserInfos>( builder: (context, userInfos, child) { return AppBar(title: Text(userInfos.money.toString())); }, ), body: PageView( children: [ Page1(), Page2(), ], ), ); } }
- 修改Page1,调用状态方法:
class Page1 extends StatefulWidget { const Page1({super.key}); @override State<Page1> createState() => _Page1State(); } class _Page1State extends State<Page1> { @override Widget build(BuildContext context) { // 获取实例,listen设为false避免不必要重建 final userInfos = Provider.of<UserInfos>(context, listen: false); return Center( child: ElevatedButton( onPressed: () { userInfos.decreaseMoney(); // 调用方法修改余额 }, child: const Text('decrease money')), ); } }
内容的提问来源于stack exchange,提问作者Berat Yıldırım
相关产品推荐
相关产品推荐

