it-swarm.com.de

SnackBar in Flatter anzeigen

Ich möchte eine einfache SnackBar in dem Stateful-Widget von Flutter anzeigen. Meine Anwendung erstellt eine neue Instanz von MaterialApp mit einem stateful-Widget mit dem Namen MyHomePage.

Ich versuche, die SnackBar in der showSnackBar () -Methode anzuzeigen. Es schlägt jedoch fehl mit 'Die Methode' showSnackBar 'wurde für null' aufgerufen.

Was ist los mit diesem 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)
    ));
  }
}

LÖSUNG:

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)
    ));
  }
}

Es gibt drei Probleme. Das erste ist, dass Sie nirgendwo ein Gerüst haben und das Gerüst-Widget weiß, wie man Snackbars anzeigt. Das zweite ist, dass Sie einen Schlüssel haben, mit dem Sie das Gerüst erreichen können, aber Sie haben ihn stattdessen auf eine Polsterung gelegt (und Paddings kennt sich mit Snackbars nicht aus). Der dritte Grund ist, dass Sie den Schlüssel verwendet haben, bevor das Widget, mit dem er verknüpft ist, initialisiert werden konnte, da initState vor dem Erstellen aufgerufen wird.

Die einfachste Lösung besteht darin, die Zeile home in Ihrem MyApp-Widget wie folgt zu ändern:

home: new Scaffold(body: new MyHomePage()),

... und entfernen Sie dann alle Erwähnungen von _scaffoldKey und verwenden Sie stattdessen Scaffold.of(context), wo Sie derzeit _scaffoldKey.currentState haben.

29
Ian Hickson

In meinem Fall hatte ich so einen Code (im Klassenstand)

final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

void showInSnackBar(String value) {
    _scaffoldKey.currentState.showSnackBar(new SnackBar(content: new Text(value)));
}

aber ich habe den Schlüssel nicht für das Gerüst eingerichtet. Wenn ich key hinzufüge: _scaffoldKey

 @override
 Widget build(BuildContext context) {
  return new Scaffold(
    key: _scaffoldKey,
    body: new SafeArea(

snackbar fängt an zu arbeiten :)

8
Jack the Ripper

Es gibt eine bessere und sauberere Möglichkeit, eine Snackbar im Flattern anzuzeigen. Ich fand es auf die harte Tour und das Teilen so, dass es vielleicht für jemand anderen hilfreich ist. 

Sie müssen in Ihrem Hauptanwendungsteil keine Änderungen vornehmen

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
  return new MaterialApp(
    title: 'MyApp',
    theme: new ThemeData(
    primarySwatch: Colors.orange),
    home: new MainPage());
  }
}

Page State Code ist, wo sich die Dinge ändern werden.

Wir wissen, dass Flutter Scaffold.of(context).showSnackBar bietet. Der Kontext sollte jedoch der Kontext eines Nachkommens eines Scaffolds sein und nicht der Kontext, der ein Scaffold beinhaltet. Um Fehler zu vermeiden, müssen wir einen BuildContext für den Rumpf des Scaffold verwenden und ihn wie unten in einer Variablen speichern.

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);                                                              
  }                                                                                                                   
}     

Nun können Sie diese Funktion von überall aus aufrufen und die Snackbar wird angezeigt. Ich verwende es beispielsweise zum Anzeigen von Internetkonnektivitätsnachrichten. 

7
Wahib Ul Haq

initState wurde vor build aufgerufen. Ich denke, _scaffoldKey.currentState wurde beim Aufruf nicht initialisiert.

Ich weiß nicht, ob Sie eine ScaffoldState von initState bekommen können. Wenn Sie Ihren Code ändern, können Sie die Snackbar aus der build-Methode anzeigen mit:

Scaffold.of(context).showSnackBar(new SnackBar(new Text(value)));
3

Falls jemand eine Snackbar auf initState() initialisieren möchte (mit anderen Worten, wenn die Seite hier geladen wird, ist meine Lösung) Ich gehe davon aus, dass Sie bereits den _scaffoldKey vorhanden haben.

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
Scaffold.of(context).showSnackBar(
     SnackBar(content: Text("Thanks for using snackbar",
     textAlign: TextAlign.center, style: TextStyle(fontSize: 16.0, fontWeight: 
     FontWeight.bold),), duration: Duration(seconds: 2), backgroundColor: Colors.red,)
);
1
yubaraj poudel

Ich habe es geschafft, arbeite für mich :)

@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

Um eine Snackbar in initState () zu initialisieren, können Sie eine Funktion ausführen, nachdem das Layout erstellt wurde.

void initState() {
super.initState();
WidgetsBinding.instance
    .addPostFrameCallback((_) => _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("Your message here..")));}
0
Syed Ahmed

sie können dies verwenden:

final _scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: AppBar(


    ),
  }
}

und dann kann in onPressed() dieser Code hinzugefügt werden

_scaffoldKey.currentState.showSnackBar(
       new SnackBar(
          content: new Text('Hello this is snackbar!')
       )
);
0
Rizki Syaputra