Reputation: 197
Three Questions:
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,
),
);
}
}
The above code throws an error when loading.
Upvotes: 5
Views: 3515
Reputation: 927
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('this is an example of snackhar.'),
action: SnackBarAction(
label: 'Ok',
onPressed: () {
// Code to execute.
},
),
),
);
Upvotes: 0
Reputation: 544
This worked for me :)
@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);
});
}
Upvotes: 0
Reputation: 537
instead of putting it inside the initState() put it in didChangeDependencies()
@override
void didChangeDependencies () {
print('In Init State Stream Builder');
_showSnackbar(context);
super.didChangeDependencies();
}
Upvotes: 0
Reputation: 15535
In flutter context
will be available only after build has been completed, You can use either Future
or WidgetsBinding.instance.addPostFrameCallback
or SchedulerBinding.instance.addPostFrameCallback
.
But I hope you will get same result if you move your _showSnackbar(context);
to build
method like this.
@override
Widget build(BuildContext context) {
_showSnackbar(context);
return Scaffold(
body: Center(
child: Text("Hello World"),
),
);
}
Upvotes: 0
Reputation: 1614
To initialise a Snackbar on initState(), either you put a delay or you can execute a function after the layout is built like this :
void initState() {
super.initState();
WidgetsBinding.instance
.addPostFrameCallback((_) => _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("Your message here..")));
}
Upvotes: 7
Reputation: 18770
I am going to answer the first question here. You have two problems here.
In Flutter, you cannot call Scaffold.of(context)
within the widget that has Scaffold inside the build method. Scaffold.of(context)
has to always be called from a context that has a Scaffold
as its ancestors.
If you want to call showSnackbar
inside initState, you have to call it inside a delayed function. The duration can be 0.
I have a simple example here to show a
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')));
}
}
Upvotes: 5