Как обновить состояние страницы после Navigator.pop() из окна предупреждения
У меня есть 2 страницы в моем приложении Flutter - 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 ответ
Вы могли бы использовать await
Ключевое слово, чтобы ждать, пока пользователь не вытолкнет Widget
,
floatingActionButton: FloatingActionButton(
onPressed: () async {
await Navigator.of(context).push(MaterialPageRoute(builder: (context) => ItemListPage(listName: 'Untitled',listItems: null,)));
setState(() {});
},
child: Icon(Icons.add),),