在AlertDialog中使用Provider无法实时更新UI的问题如何解决?
问题根因
showDialog弹出的对话框本身默认不会监听父页面的Provider状态更新,你提前在页面的build方法中将_playerList赋值为局部固定列表,即使Provider触发状态更新,对话框内引用的还是初始化时的旧列表数据,只有关闭后重新打开才会重新获取最新值。
修复方案
在对话框内部使用Consumer包裹需要响应状态变化的列表部分,直接在对话框的构建逻辑中实时从Provider获取最新的玩家列表数据,修改后的代码如下:
floatingActionButton: FloatingActionButton( onPressed: () { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text('Player List'), // 用Consumer监听PlayerList的状态变化 content: Consumer<PlayerList>( builder: (context, playerListData, child) { // 每次状态更新时重新获取最新的玩家列表 List<Player> _playerList = playerListData.playerList; return Column( mainAxisSize: MainAxisSize.min, children: [ Container( height: MediaQuery.of(context).size.height * 0.5, width: MediaQuery.of(context).size.width * 0.5, child: ListView.builder( shrinkWrap: true, itemCount: _playerList.length, itemBuilder: (BuildContext context, int index) { return ListTile( title: Text( _playerList[index].name, style: Theme.of(context).textTheme.headline6, ), trailing: IconButton( icon: Icon(Icons.delete), color: Theme.of(context).errorColor, onPressed: () => playerListData.deletePlayer(index), )); }, ), ), ] ); } ), ); } ); }, child: Icon(Icons.person_add), )
原理说明
Consumer会自动监听PlayerList的状态变化,当你调用deletePlayer触发notifyListeners时,对话框内的列表组件会自动重建,加载最新的玩家列表,不需要手动刷新或者关闭重开对话框。- 不要提前在父页面的build方法中把玩家列表存为固定局部变量给对话框使用,要在需要用到列表数据的组件层级实时从Provider取最新值,保证数据和状态源一致。
内容的提问来源于stack exchange,提问作者P200p
相关产品推荐
相关产品推荐

