как обновить состояние страницы после Navigator.pop () из окна предупреждения - PullRequest
0 голосов
/ 04 января 2019

В моем приложении Flutter есть 2 страницы - ShoppingListsPage и ItemsListPage. У меня есть кнопка FloatingActionButton в ShoppingListsPage, в результате чего пользователь переходит на ItemsListPage, где он может добавлять элементы из ListView в список покупок, а затем сохранять список, нажимая кнопку на панели приложений. Когда пользователь нажимает кнопку «Готово» на панели приложений, я отображаю диалоговое окно AlertDialog, чтобы запросить у пользователя имя для списка. Как только пользователь вводит имя списка и нажимает кнопку «Сохранить» в диалоговом окне, я сохраняю детали списка в базе данных SQLite (я использую плагин sqflite для взаимодействия с базой данных), а затем хочу переместить пользователя обратно на ShoppingListsPage, где только что созданный список должен быть отображен.

Учитывая этот контекст, я вижу, что когда я сохраняю список в базе данных и перехожу к ShoppingListsPage с помощью Navigate.pop (context), выполняется код для извлечения списков покупок из базы данных, но он не извлекает последнее добавление и, следовательно, ListView в ShoppingListsPage не обновляется с последними изменениями. Однако, если я перейду на другую страницу и вернусь, отобразится вновь добавленный список. Похоже, что выборка из базы данных в ShoppingListsPage происходит до того, как данные сохраняются в базе данных. Как убедиться, что выборка прошла успешно (с последними данными) из базы данных?

В соответствующей заметке, как лучше убедиться, что асинхронная функция, которую я должен сохранить для сохранения данных в базе данных, вызывается и завершается до того, как Navigator.pop (context) переместит пользователя на предыдущий экран? Все мои функции для взаимодействия с базой данных SQLite являются асинхронными функциями.

Вот код для отображения диалогового окна на странице ItemsList, сохранения данных и возврата к ShoppingListsPage:

_showListNameDialog() async {
    final textController = new TextEditingController();
    String retVal = await showDialog<String>(
        context: context,
        child: AlertDialog(
          contentPadding: EdgeInsets.all(12.0),
          content: Row(
            children: <Widget>[
              Expanded(
                child: TextField(
                  decoration: InputDecoration(
                      labelText: 'List Name',
                      hintText: 'Monthly groceries'
                  ),
                  controller: textController,
                ),
              )
            ],
          ),
          actions: <Widget>[
            FlatButton(
                onPressed: (){
                  Navigator.pop(context);
                },
                child: Text('Cancel')
            ),
            FlatButton(
                onPressed: (){
                  addShoppingListItemsToDB(textController.text, shoppingListItemMap);
                  Navigator.pop(context, textController.text);
                },
                child: Text('Save')
            )
          ],
        )
    );
    Navigator.pop(context);
    setState(() {
    });
  }

Вот код в ShoppingListsPage для получения и отображения данных:

Future<List<ShoppingList>> getShoppingLists() async {
  DBHelper dbClient = DBHelper();
  return dbClient.getShoppingLists();
}

@override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text('Shopping Lists'),
      ),
      body: Container(
        padding: EdgeInsets.all(12.0),
        child: FutureBuilder<List<ShoppingList>>(
            future: getShoppingLists(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return ListView.builder(
                    itemCount: snapshot.data.length,
                    itemBuilder: (context, index) {
                      String listName = snapshot.data[index].listName;
                      return Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            ListTile(
                              leading: CircleAvatar(
                                child: Text(listName==''?'u':listName[0]),
                              ),
                              title: Text(snapshot.data[index].listName, style: TextStyle(fontSize: 18.0),),
                              subtitle: Text('Created at ${snapshot.data[index].createdAt}', style: TextStyle(color: Colors.grey),),
                              onTap: () {
                                Navigator.push(
                                    context,
                                    MaterialPageRoute(builder: (context) => ShoppingListItemsPage(list_name: snapshot.data[index].listName,))
                                );
                              },
                            ),
                            Divider()
                          ]
                      );
                    }
                );
              } else if (snapshot.hasError) {
                return Text('Error: ${snapshot.error}');
              }
              return Container(alignment: AlignmentDirectional.center, child: CircularProgressIndicator(),);
            }
        ),
      ),
      floatingActionButton: FloatingActionButton(
          onPressed: (){
            Navigator.of(context).push(MaterialPageRoute(builder: (context) => ItemListPage(listName: 'Untitled',listItems: null,)));
          },
      child: Icon(Icons.add),),
    );
  }

1 Ответ

0 голосов
/ 04 января 2019

Вы можете использовать ключевое слово await, чтобы подождать, пока пользователь не выдвинет Widget.

         floatingActionButton: FloatingActionButton(
                  onPressed: () async {
                    await Navigator.of(context).push(MaterialPageRoute(builder: (context) => ItemListPage(listName: 'Untitled',listItems: null,)));
                    setState(() {});
                  },
              child: Icon(Icons.add),),
...