Je veux afficher un simple SnackBar dans le widget dynamique de Flutter . Mon application crée une nouvelle instance de MaterialApp avec un widget dynamique appelé MyHomePage.
J'essaie de montrer le SnackBar dans la méthode showSnackBar (). Mais cela échoue avec 'La méthode' showSnackBar 'était appelée sur null'.
Quel est le problème avec ce code?
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@override
void initState() {
super.initState();
showInSnackBar("Some text");
}
@override
Widget build(BuildContext context) {
return new Padding(
key: _scaffoldKey,
padding: const EdgeInsets.all(16.0),
child: new Text("Simple Text")
);
}
void showInSnackBar(String value) {
_scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text(value)
));
}
}
SOLUTION:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new Scaffold(body: new MyHomePage()),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
showInSnackBar("Some text");
return new Padding(
padding: const EdgeInsets.all(16.0),
child: new Scaffold(
body: new Text("Simple Text")
)
);
}
void showInSnackBar(String value) {
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text(value)
));
}
}
Dans mon cas, j'avais un code comme celui-ci (en état de classe)
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
void showInSnackBar(String value) {
_scaffoldKey.currentState.showSnackBar(new SnackBar(content: new Text(value)));
}
mais je n'ai pas configuré la clé pour échafaudage . donc quand j'ajoute clé: _scaffoldKey
@override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
body: new SafeArea(
snackbar commence à travailler :)
Il existe un moyen plus efficace et plus propre d’afficher une barre de défilement à la volée. Je l'ai trouvé à la dure et à partager, de sorte que peut-être que cela soit utile pour quelqu'un d'autre.
Pas besoin de changer dans votre partie principale de l'application
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'MyApp',
theme: new ThemeData(
primarySwatch: Colors.orange),
home: new MainPage());
}
}
Code d'état de la page est l'endroit où les choses vont changer.
Nous savons que Flutter fournit Scaffold.of(context).showSnackBar
. Cependant, le contexte devrait être le contexte d'un descendant d'un échafaudage et non le contexte qui inclut un échafaudage. Afin d'éviter les erreurs, nous devons utiliser un BuildContext pour le corps de l'échafaudage et le stocker dans une variable, comme ci-dessous.
class MainPageState extends State<MainPage> {
BuildContext scaffoldContext;
@override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.grey,
appBar: new AppBar(
title: const Text(APP_TITLE),
),
body: new Builder(builder: (BuildContext context) {
scaffoldContext = context;
return new Center(
child: new Text('Hello World', style: new TextStyle(fontSize: 32.0)),
);
}));
}
void createSnackBar(String message) {
final snackBar = new SnackBar(content: new Text(message),
backgroundColor: Colors.red);
// Find the Scaffold in the Widget tree and use it to show a SnackBar!
Scaffold.of(scaffoldContext).showSnackBar(snackBar);
}
}
Maintenant, vous pouvez appeler cette fonction de n’importe où et affichera le Snackbar. Par exemple, je l'utilise pour afficher des messages de connectivité Internet.
initState
été appelé avant build
Je suppose que _scaffoldKey.currentState
n'a pas été initialisé lors de l'appel.
Je ne sais pas si vous pouvez obtenir un ScaffoldState
de initState
. Si vous modifiez votre code, vous pouvez afficher la méthode du snackbar à partir de la méthode build
avec:
Scaffold.of(context).showSnackBar(new SnackBar(new Text(value)));
Si quelqu'un cherche à initialiser une Snackbar
sur initState()
(en d'autres termes, lorsque la page se charge, voici ma solution). De plus, je suppose que vous avez déjà le _scaffoldKey
en place.
void initState() {
super.initState();
Future.delayed(Duration(seconds: 1)).then(
(_) => _displaySnackbar
);
}
// Display Snackbar
void get _displaySnackbar {
_scaffoldKey.currentState.showSnackBar(SnackBar(
duration: Duration(minutes: 1),
content: Text('Your snackbar message')
));
}
Je l'ai fait, travaille pour moi :)
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Demo')
),
body: new Builder(
// Create an inner BuildContext so that the onPressed methods
// can refer to the Scaffold with Scaffold.of().
builder: (BuildContext context) {
return new Center(
child: new RaisedButton(
child: new Text('SHOW A SNACKBAR'),
onPressed: () {
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text('Hello!'),
));
},
),
);
},
),
);
}
Pour initialiser une Snackbar sur initState (), vous pouvez exécuter une fonction après la construction de la présentation.
void initState() {
super.initState();
WidgetsBinding.instance
.addPostFrameCallback((_) => _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("Your message here..")));}