323 votes

Scaffold.of () appelé avec un contexte qui ne contient pas d'échafaudage

Comme vous pouvez le voir mon bouton est à l'intérieur de l'Échafaudage de son corps. Mais j'ai cette exception:

Échafaudage.de() est appelé avec un contexte qui ne contiennent pas d'un Échafaudage.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('SnackBar Playground'),
      ),
      body: Center(
        child: RaisedButton(
          color: Colors.pink,
          textColor: Colors.white,
          onPressed: _displaySnackBar(context),
          child: Text('Display SnackBar'),
        ),
      ),
    );
  }
}

_displaySnackBar(BuildContext context) {
  final snackBar = SnackBar(content: Text('Are you talkin\' to me?'));
  Scaffold.of(context).showSnackBar(snackBar);
}

EDIT:

J'ai trouvé une autre solution à ce problème. Si nous donnons un Échafaudage d'une clé qui est GlobalKey, nous pouvons afficher la Buvette comme suit, sans besoin d'envelopper notre corps avec le Générateur de widget. Le widget de retour Échafaudage doit être Dynamique widget mais.:

 _scaffoldKey.currentState.showSnackBar(snackbar); 

416voto

Rémi Rousselet Points 45139

Cette exception se produit parce que vous êtes à l'aide de l' context du widget instancié Scaffold. Pas l' context d'un enfant de Scaffold.

Vous pouvez résoudre ce problème en utilisant simplement un autre contexte :

Scaffold(
    appBar: AppBar(
        title: Text('SnackBar Playground'),
    ),
    body: Builder(
        builder: (context) => 
            Center(
            child: RaisedButton(
            color: Colors.pink,
            textColor: Colors.white,
            onPressed: () => _displaySnackBar(context),
            child: Text('Display SnackBar'),
            ),
        ),
    ),
);

Notez que même si nous utilisons Builder ici, ce n'est pas la seule façon d'obtenir un autre BuildContext.

Il est également possible d'extraire le sous-arbre dans un autre Widget (généralement à l'aide d' extract widget refactor)

180voto

Lebohang Mbele Points 1006

Vous pouvez utiliser un GlobalKey . Le seul inconvénient est que l'utilisation de GlobalKey n'est peut-être pas le moyen le plus efficace de le faire.

Une bonne chose à ce sujet est que vous pouvez également transmettre cette clé à d'autres classes de widgets personnalisés qui ne contiennent aucun échafaudage. Voir ( ici )

 class HomePage extends StatelessWidget {
  final _scaffoldKey = GlobalKey<ScaffoldState>(); \\ new line
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,                           \\ new line
      appBar: AppBar(
        title: Text('SnackBar Playground'),
      ),
      body: Center(
        child: RaisedButton(
          color: Colors.pink,
          textColor: Colors.white,
          onPressed: _displaySnackBar(context),
          child: Text('Display SnackBar'),
        ),
      ),
    );
  }
  _displaySnackBar(BuildContext context) {
    final snackBar = SnackBar(content: Text('Are you talkin\' to me?'));
    _scaffoldKey.currentState.showSnackBar(snackBar);   \\ edited line
  }
}
 

81voto

Sanjayrajsinh Points 1098

Deux façons de résoudre ce problème

1) Utilisation du widget Builder

 Scaffold(
    appBar: AppBar(
        title: Text('My Profile'),
    ),
    body: Builder(
        builder: (ctx) => RaisedButton(
            textColor: Colors.red,
            child: Text('Submit'),
            onPressed: () {
                 Scaffold.of(ctx).showSnackBar(SnackBar(content: Text('Profile Save'),),);
            }               
        ),
    ),
);
 

2) Utilisation de GlobalKey

 class HomePage extends StatelessWidget {

  final globalKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
     return Scaffold(
       key: globalKey,
       appBar: AppBar(
          title: Text('My Profile'),
       ),
       body:  RaisedButton(
          textColor: Colors.red,
          child: Text('Submit'),
          onPressed: (){
               final snackBar = SnackBar(content: Text('Profile saved'));
               globalKey.currentState.showSnackBar(snackBar);
          },
        ),
     );
   }
}
 

29voto

SANAT Points 3563

Vérifier à partir de la documentation de la méthode:

Lorsque l'Échafaudage est en fait créé dans le même construire la fonction, la contexte argument à la fonction de création ne peut pas être utilisé pour trouver l' Échafaudage (car il est "au-dessus" du widget être retourné). Dans de tels cas, la technique suivante avec un Générateur peut être utilisé pour fournir une nouvelle portée avec un BuildContext qui est "sous" l'Échafaudage:

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text('Demo')
    ),
    body: Builder(
      // Create an inner BuildContext so that the onPressed methods
      // can refer to the Scaffold with Scaffold.of().
      builder: (BuildContext context) {
        return Center(
          child: RaisedButton(
            child: Text('SHOW A SNACKBAR'),
            onPressed: () {
              Scaffold.of(context).showSnackBar(SnackBar(
                content: Text('Hello!'),
              ));
            },
          ),
        );
      },
    ),
  );
}

Vous pouvez vérifier la description de la méthode de docs

17voto

Un moyen simple de résoudre ce problème sera de créer une clé pour votre échafaudage comme cette finale avec le code suivant:

Premier: GlobalKey<ScaffoldState>() _scaffoldKey = GlobalKey<ScaffoldState> ();

Seconde: attribuez la clé à votre échafaudage key: _scaffoldKey

Troisièmement: appelez la Snackbar en utilisant _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("Welcome")));

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X