#flutter #flutter-layout #snackbar
#всплывающее окно #всплывающее окно-макет #панель закусок
Вопрос:
Три вопроса:
- Как загрузить панель закусок в flutter в initState или когда приложение загружает начальный экран? У меня есть приведенный ниже код, но он выдает ошибку и не загружает текст на экране.
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
void initState() {
print('In Init State Stream Builder');
_showSnackbar(context);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("Hello World"),
),
);
}
void _showSnackbar(BuildContext ctx) {
Scaffold.of(ctx).showSnackBar(
SnackBar(
content: ListTile(
onTap: () {
Scaffold.of(ctx).hideCurrentSnackBar();
},
subtitle: Text("and i'm a subtitle"),
trailing: Icon(Icons.check),
),
duration: Duration(
days: 1,
),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
behavior: SnackBarBehavior.floating,
),
);
}
}
Приведенный выше код выдает ошибку при загрузке.
Комментарии:
1. Привет, спасибо, что присоединились к stackoverflow и задали свой первый вопрос! Здесь, в stackoverflow, вы всегда должны задавать по одному вопросу за сообщение. В противном случае ваш вопрос может быть закрыт.
Ответ №1:
Чтобы инициализировать панель закусок в initState(), либо вы устанавливаете задержку, либо вы можете выполнить функцию после построения макета следующим образом :
void initState() {
super.initState();
WidgetsBinding.instance
.addPostFrameCallback((_) => _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("Your message here..")));
}
Ответ №2:
Здесь я собираюсь ответить на первый вопрос. Здесь у вас две проблемы.
- В Flutter вы не можете вызывать
Scaffold.of(context)
внутри виджета, который имеет каркас внутри метода сборки.Scaffold.of(context)
всегда должен вызываться из контекста, который имеет aScaffold
в качестве своих предков. - Если вы хотите вызвать
showSnackbar
внутри initState, вы должны вызвать его внутри отложенной функции. Длительность может быть равна 0.
Здесь у меня есть простой пример, чтобы показать
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: ChildWidget(),
);
}
}
class ChildWidget extends StatefulWidget {
@override
_ChildWidgetState createState() => _ChildWidgetState();
}
class _ChildWidgetState extends State<ChildWidget> {
@override
Widget build(BuildContext context) {
return Container();
}
@override
void initState() {
Future<Null>.delayed(Duration.zero, () {
_showSnackbar();
});
super.initState();
}
void _showSnackbar() {
Scaffold.of(context).showSnackBar(SnackBar(content: Text('content')));
}
}
Ответ №3:
В flutter context
будет доступен только после завершения сборки, вы можете использовать либо Future
или WidgetsBinding.instance.addPostFrameCallback
, либо SchedulerBinding.instance.addPostFrameCallback
.
Но я надеюсь, что вы получите тот же результат, если переместите свой _showSnackbar(context);
build
метод to следующим образом.
@override
Widget build(BuildContext context) {
_showSnackbar(context);
return Scaffold(
body: Center(
child: Text("Hello World"),
),
);
}
Ответ №4:
вместо того, чтобы помещать ее в initState(), поместите ее в didChangeDependencies()
@override
void didChangeDependencies () {
print('In Init State Stream Builder');
_showSnackbar(context);
super.didChangeDependencies();
}
Ответ №5:
Это сработало для меня 🙂
@override
void initState() {
super.initState();
WidgetsBinding.instance!.addPostFrameCallback((_) {
// do what you want here
final snackBar = SnackBar(
content: const Text('Yay! A SnackBar!'),
action: SnackBarAction(
label: 'Undo',
onPressed: () {
// Some code to undo the change.
},
),
);
// Find the ScaffoldMessenger in the widget tree
// and use it to show a SnackBar.
ScaffoldMessenger.of(context).showSnackBar(snackBar);
});
}