Использование поставщика в диалоговом окне предупреждения не работает

#flutter #dart

Вопрос:

Я пытаюсь управлять состоянием «Список игроков» на двух экранах:

Приведенный ниже код показывает, как был создан поставщик

 class PlayerList with ChangeNotifier {
  List<Player> _playerList = [];

  List<Player> get playerList {
    return [..._playerList];
  }

  void addPlayer(Player player) {
    _playerList.add(player);
    notifyListeners();
  }

  void deletePlayer(int index) {
    _playerList.removeAt(index);
    notifyListeners();
  }
}

 

На экране 1 все работает идеально. Однако, когда я делаю то же самое, но затем в AlertDialog, обновленное значение отображается только после закрытия диалогового окна и его повторного открытия.

В приведенном ниже коде показана соответствующая часть метода сборки.

 @override
  Widget build(BuildContext context) {
    PlayerList _playerListData = Provider.of<PlayerList>(context);
    List<Player> _playerList = _playerListData.playerList;
    return WillPopScope(
      onWillPop: () async => showDialog(
          context: context,
          builder: (context) => AlertDialog(
                  title: Text(
                      'Are you sure you want to leave? The current game will be lost.'),
                  actions: <Widget>[
                    ElevatedButton(
                        child: Text('Yes'),
                        onPressed: () => Navigator.of(context).pop(true)),
                    ElevatedButton(
                        child: Text('No'),
                        onPressed: () => Navigator.of(context).pop(false)),
                  ])),
      child: Scaffold(
        backgroundColor: Color(0xFF6ca0dc),
        body: Center(
          child: Column(children: [
            _playChallenge(_playerList),
          ]),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            showDialog(
                context: context,
                builder: (BuildContext context) {
                  return AlertDialog(
                    title: Text('Player List'),
                    content: Column(mainAxisSize: MainAxisSize.min, children: [
                      Container(
                        height: MediaQuery.of(context).size.height *
                            0.5, // Change as per your requirement
                        width: MediaQuery.of(context).size.width *
                            0.5, // Change as per your requirement
                        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),
                                ));
                          },
                        ),
                      ),

 

Как я могу решить эту проблему?

Ответ №1:

Я решил проблему, добавив сборщик состояний и используя Provider.of внутри сборщика состояний. Видеть:

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async => showDialog(
          context: context,
          builder: (context) => AlertDialog(
                  title: Text(
                      'Are you sure you want to leave? The current game will be lost.'),
                  actions: <Widget>[
                    ElevatedButton(
                        child: Text('Yes'),
                        onPressed: () => Navigator.of(context).pop(true)),
                    ElevatedButton(
                        child: Text('No'),
                        onPressed: () => Navigator.of(context).pop(false)),
                  ])),
      child: Scaffold(
        backgroundColor: Color(0xFF6ca0dc),
        body: Center(
          child: Column(children: [
            _playChallenge(Provider.of<PlayerList>(context).playerList),
          ]),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            showDialog(
                context: context,
                builder: (BuildContext context) {
                  return StatefulBuilder(builder: (context, setState) {
                    PlayerList _playerListData =
                        Provider.of<PlayerList>(context);
                    List<Player> _playerList = _playerListData.playerList;
                    return AlertDialog(
                      title: Text('Player List'),
                      content:
                          Column(mainAxisSize: MainAxisSize.min, children: [
                        Container(
                          height: MediaQuery.of(context).size.height *
                              0.5, // Change as per your requirement
                          width: MediaQuery.of(context).size.width *
                              0.5, // Change as per your requirement
                          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),
                                  ));
                            },
                          ),
                        ),