#flutter #dart #toast #snackbar
Вопрос:
В поисках примеров использования flutter SnackBar
с ScaffoldMessenger
, я нашел только использование с onPressed
функцией:
Widget build(BuildContext context) {
return Container(
child: ElevatedButton(
child: ...,
onPressed: () => _showToast(context),
));
}
void _showToast(BuildContext context) {
final scaffold = ScaffoldMessenger.of(context);
scaffold.showSnackBar(
SnackBar(content: const Text('Added to favorite')),
);
}
}
но ни один из примеров не объясняет, почему его нужно использовать только с onPressed,
поэтому я попробовал его сам и использовал непосредственно внутри функции сборки:
Widget build(BuildContext context) {
_showToast(context); <---
return Container(
child: ElevatedButton(
...,
));
}
но чем я получил эту ошибку:
и я не уверен, почему это происходит.
В итоге я дал Эшафоту ключ и использовал этот GlobalKey<ScaffoldState>
подход, но я действительно хочу понять, почему использование ScaffoldMessenger.of(context).showSnackBar()
без обратного вызоваonPressed не сработало
Ответ №1:
в то время ScaffoldMessenger.of(context)
как нам нужно дать некоторое время для правильной визуализации(для полного эшафота). мы можем узнать время по addPostFrameCallback
. Также, если вы попытаетесь показать середину виджетов, 1-я часть будет отображаться, но остальные виджеты столкнутся с этой проблемой.
вот суть build
метода.
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
_showToast(context);
});
чтобы правильно понять концепцию, мы можем сделать что-то вроде этого.
Scaffold(
body: Container(
height: 100,
color: Colors.cyanAccent,
child: Column(
children: [
Text("This text will render "),
Builder(builder: (context) {
_showToast(context);
///but you will be able to see Message
return Text("it will cause error");
}),
Text("This text will not render "),
],
),
),
);
Комментарии:
1. Я принял этот ответ, поскольку он объясняет концепцию полного рендеринга лесов и дает пример для этой концепции.
Ответ №2:
Попробуйте добавить или объявить свою закусочную в будущем.делейд
Future.delayed(Duration.zero, () async {
yourSnackBarFunction();
});
Комментарии:
1. Моя цель-понять причину, по которой я получаю ошибку. хотя я предполагаю, что ваше решение сработает…
2. Я не рекомендую этого делать, это как-то «обманывает» рамки и вообще не рекомендуется.
3. Я вроде как решил проблему с GlobalKey (как я уже упоминал в посте), но я действительно хочу понять, почему это происходит
4. Подумайте о методе «сборки» как о рецепте для движка Flutter, как собрать свой виджет, если произойдет что-то, что приведет к необходимости перестройки. Видишь api.flutter.dev/flutter/material/ScaffoldState/build.html .
5. @vigdora Я думаю о будущем. удалено, которое выполняет свои вычисления с задержкой. [Вычисление] будет выполнено по истечении заданного [времени], и будущее завершится результатом вычисления.
Ответ №3:
В Flutter функция сборки вызывается самой платформой всякий раз, когда требуется перестроить виджет. Это может произойти много раз!
С другой стороны, вы обычно хотите отобразить тост / закусочную, когда хотите о чем-то сообщить своему пользователю. Таким образом, вы можете отображать закусочную из onPressed и многих других мест, но сама функция сборки предназначена только для создания виджета и не отвечает напрямую на действия пользователя.
Комментарии:
1. Спасибо, но когда flutter связывает вас с использованием контекста с помощью scaffoldMessenger, он ограничивает использование его только методом сборки в виджетах без состояния… и я, возможно, захочу использовать тосты вне функции сборки..
2. Возможно, я ошибаюсь, но я думаю, что вы можете получить доступ к контексту и из других мест, а не только из метода сборки. Например, если вы объявляете метод в «class _SomeState расширяет состояние<Некоторые>», у вас есть контекст в методе. Попробуйте и извините, если я ввожу вас в заблуждение, но я помню, как использовал это.
3. api.flutter.dev/flutter/widgets/State/context.html
4. Проверьте ссылку выше, мне кажется, что есть средство получения с именем «контекст», к которому вы можете получить доступ из объектов состояния. Немного сбивает с толку то, что функции сборки получают это как параметр функции с тем же именем.
5. Я проверю вышесказанное, но я думаю, что ваша идея связана с виджетами с отслеживанием состояния, и мой вопрос больше касается состояния без состояния, я начинаю чувствовать, что ключевой подход (GlobalKey<ScaffoldState>) является правильным, поскольку он позволит мне более гибко