widgets switch modal card flutter scaffold snackbar

switch - modal flutter



Scaffold.of() llamado con un contexto que no contiene un andamio (4)

Esta excepción ocurre porque está utilizando el context del widget que creó una instancia de Scaffold . No es el context de un niño de Scaffold .

Puedes resolver esto usando solo un contexto diferente:

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''), ), ), ), );

Tenga en cuenta que si bien estamos utilizando Builder aquí, esta no es la única forma de obtener un BuildContext diferente.

También es posible extraer el subárbol en un Widget diferente (usualmente utilizando extract widget refactor de extract widget )

Como puedes ver mi botón está dentro del cuerpo de Scaffold. Pero me sale esta excepción:

Scaffold.of () llamado con un contexto que no contiene un andamio.

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

EDITAR:

Encontré otra solución a este problema. Si le damos a Scaffold una clave que es GlobalKey, podemos mostrar SnackBar como sigue sin necesidad de envolver nuestro cuerpo con el widget Builder. Sin embargo, el widget que devuelve Scaffold debería ser un estado de estado:

_scaffoldKey.currentState.showSnackBar(snackbar);


Puedes usar un GlobalKey . El único inconveniente es que el uso de GlobalKey puede no ser la forma más eficiente de hacerlo.

Una buena cosa de esto es que también puede pasar esta clave a otra clase de widgets personalizados que no contenga ningún andamio. Ver ( here )

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 }


Una forma sencilla de resolver este problema será crear una clave para su andamio como esta final con el siguiente código:

_scaffoldKey = GlobalKey<ScaffoldState>(); y llama a tu snackBar usando el operador de puntos.

_scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("Welcome")));


Verifique esto en la documentación del método:

Cuando el Andamio se crea realmente en la misma función de compilación, el argumento de contexto de la función de compilación no se puede usar para encontrar el Andamio (ya que está "arriba" del widget que se está devolviendo). En tales casos, la siguiente técnica con un Builder se puede usar para proporcionar un nuevo alcance con un BuildContext que está "debajo" del Andamio:

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

Puedes consultar la descripción desde la documentación del método.