web-dev-qa-db-fra.com

Afficher Snack Bar dans Flutter

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 :)

8
Jack the Ripper

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. 

7
Wahib Ul Haq

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)));
3
Alexandre Ardhuin

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')
  ));
}
2
Alvin Konda

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!'),
              ));
            },
          ),
        );
      },
    ),
  );
}
1
Programador

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..")));}
0
Syed Ahmed