Flutter点击按钮调用setState无法更新Text组件值问题求助
问题根因
你在_AnaMenuState中手动实例化的BottomInfoBarState altPanel = BottomInfoBarState();和你作为bottomNavigationBar传入的BottomInfoBar()组件对应的状态实例不是同一个对象。你调用的是游离在组件树之外的状态对象的方法,自然不会触发实际挂载在页面上的底部栏更新。
方案1:通过GlobalKey获取底部栏真实状态实例
该方案改动最小,直接就能生效,修改主页面代码如下:
class _AnaMenuState extends State<AnaMenu> { // 定义GlobalKey关联BottomInfoBar final GlobalKey<BottomInfoBarState> bottomBarKey = GlobalKey(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Akıllı Ev Sistemleri'), ), body: Center( child: ElevatedButton( onPressed: () { // 通过key获取真实挂载的状态实例调用方法 bottomBarKey.currentState?.degisenDegerler(); AlertBoxDialog.alertBoxCreator( context: context, title: "Başlık", desc: 'Açıklama', imageLocation: AlertBoxDialog.yuksekSicaklikLogo); }, child: Text("ISI UYARISI"), ), ), drawer: DrawerPanel(), // 把key传给BottomInfoBar组件 bottomNavigationBar: BottomInfoBar(key: bottomBarKey), ); } }
方案2:状态提升(更符合Flutter最佳实践)
如果后续有多处需要修改底部栏的数值,建议把状态放到父组件AnaMenu中管理,通过参数传递给底部栏,可维护性更强:
- 修改主页面代码:
class _AnaMenuState extends State<AnaMenu> { int _sicaklikSeviyesi = 15; Color _sicaklikLogoRengi = Colors.white; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Akıllı Ev Sistemleri'), ), body: Center( child: ElevatedButton( onPressed: () { setState(() { _sicaklikSeviyesi = 100; if (_sicaklikSeviyesi < 20) { _sicaklikLogoRengi = Colors.blue; } else if (_sicaklikSeviyesi > 50) { _sicaklikLogoRengi = Colors.red; } else { _sicaklikLogoRengi = Colors.yellow; } }); AlertBoxDialog.alertBoxCreator( context: context, title: "Başlık", desc: 'Açıklama', imageLocation: AlertBoxDialog.yuksekSicaklikLogo); }, child: Text("ISI UYARISI"), ), ), drawer: DrawerPanel(), bottomNavigationBar: BottomInfoBar( sicaklikSeviyesi: _sicaklikSeviyesi, sicaklikLogoRengi: _sicaklikLogoRengi, ), ); } }
- 修改底部信息栏代码,改为接收父组件传入的参数:
class BottomInfoBar extends StatefulWidget { final int sicaklikSeviyesi; final Color sicaklikLogoRengi; const BottomInfoBar({ Key? key, required this.sicaklikSeviyesi, required this.sicaklikLogoRengi, }) : super(key: key); @override BottomInfoBarState createState() => BottomInfoBarState(); } class BottomInfoBarState extends State<BottomInfoBar> { int _sesSeviyesi = 15, _hareketSeviyesi = 45, _isikSeviyesi = 75, _dumanSeviyesi = 20; @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( boxShadow: [ BoxShadow(color: Colors.black38, spreadRadius: 0, blurRadius: 10), ], ), child: ClipRRect( borderRadius: BorderRadius.only( topLeft: Radius.circular(15), topRight: Radius.circular(15)), child: BottomAppBar( color: Colors.orange[300], child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _bottomContainerCreator( Icons.local_fire_department, widget.sicaklikSeviyesi.toString(), iconColor: widget.sicaklikLogoRengi), _bottomContainerCreator( Icons.record_voice_over, "%$_sesSeviyesi"), _bottomContainerCreator( Icons.directions_walk, '%$_hareketSeviyesi'), _bottomContainerCreator(Icons.light, "%$_isikSeviyesi"), _bottomContainerCreator(Icons.cloud, "%$_dumanSeviyesi"), ], ), ), ), ); } _bottomContainerCreator(IconData icon, String text, {Color iconColor = Colors.white}) { return Container( decoration: BoxDecoration( color: Colors.grey[700], borderRadius: BorderRadius.circular(15.0)), margin: EdgeInsets.all(3), padding: EdgeInsets.all(3), height: 60, child: Column( children: [ Container( padding: EdgeInsets.all(5), child: Icon( icon, size: 27, color: iconColor, ), ), Padding( padding: const EdgeInsets.only(top: 1), child: Text( text, style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white), ), ), ], ), ); } }
内容的提问来源于stack exchange,提问作者mehmettalhairmak
相关产品推荐
相关产品推荐

