/// Common class for all views
class GerenciadorTelaLogada<C extends StatefulWidget> extends State<C> {
/// View title
final String titulo;
// Child widgets
final Widget child;
GerenciadorTelaLogada(
{@required this.titulo, this.child, this.floatingActButton});
final Widget floatingActButton;
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Text(this.titulo),
centerTitle: true,
),
// Side Menu
drawer: GMenu(),
floatingActionButton: this.floatingActButton,
// View body
body: SafeArea(
child: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(new FocusNode());
},
child: Container(
color: Color(0xff5b71b3),
padding: EdgeInsets.only(top: 10),
child: this.child,
),
),
),
);
}
}Then, I created another class that adds some functionality to
GerenciadorTelaLogadaclass:// Standard class to all views that as a Form class GerenciadorTelaLogadaCadastro<C extends StatefulWidget> extends GerenciadorTelaLogada<C> { /// Executed when clicked in save button final VoidCallback onSalvar; /// Construtor GerenciadorTelaLogadaCadastro( {@required String titulo, Widget child, @required this.onSalvar}) : super(titulo: titulo, child: child); // Adds new widgets @override Widget build(BuildContext context) { FloatingActionButton salvarFloatButton = FloatingActionButton( child: Icon( Icons.save, color: Colors.white, ), backgroundColor: Colors.green, onPressed: this.onSalvar, ); /// Return the base view with additional widgets return GerenciadorTelaLogada( titulo: this.titulo, child: this.child, floatingActButton: salvarFloatButton, ).build(context); } }Now I can create several views using that class, like so:class CBandeira extends StatefulWidget { @override _CBandeiraState createState() => _CBandeiraState(); } class _CBandeiraState extends GerenciadorTelaLogadaCadastro<CBandeira> with SingleTickerProviderStateMixin { final _formKey = GlobalKey<FormState>(); var formInputs = <GTextBox>[]; @override Widget build(BuildContext context) { return GerenciadorTelaLogadaCadastro( onSalvar: () { if (_formKey.currentState.validate()) { Scaffold.of(context).showSnackBar(new SnackBar( content: Text("Test"), )); } }, titulo: "Cadastro de Bandeira", child: Form( key: _formKey, child: ListView.separated( itemBuilder: (context, index) { return ListTile( leading: Icon( formInputs[index].icon, color: Colors.white, ), title: formInputs[index], ); }, separatorBuilder: (context, index) { return SizedBox(height: 10); }, itemCount: formInputs.length), ), ).build(context); } }Everything works fine except when I try to show a Snackbar,_CBandeiraState, onSalvarfunction return this error:I/flutter (20636): ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════ I/flutter (20636): The following assertion was thrown while handling a gesture: I/flutter (20636): Scaffold.of() called with a context that does not contain a Scaffold. I/flutter (20636): No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). This I/flutter (20636): usually happens when the context provided is from the same StatefulWidget as that whose build I/flutter (20636): function actually creates the Scaffold widget being sought. I/flutter (20636): There are several ways to avoid this problem. The simplest is to use a Builder to get a context that I/flutter (20636): is "under" the Scaffold. For an example of this, please see the documentation for Scaffold.of(): I/flutter (20636): https://api.flutter.dev/flutter/material/Scaffold/of.html I/flutter (20636): A more efficient solution is to split your build function into several widgets. This introduces a I/flutter (20636): new context from which you can obtain the Scaffold. In this solution, you would have an outer widget I/flutter (20636): that creates the Scaffold populated by instances of your new inner widgets, and then in these inner I/flutter (20636): widgets you would use Scaffold.of(). I/flutter (20636): A less elegant but more expedient solution is assign a GlobalKey to the Scaffold, then use the I/flutter (20636): key.currentState property to obtain the ScaffoldState rather than using the Scaffold.of() function. I/flutter (20636): The context used was: I/flutter (20636): CBandeira I/flutter (20636): I/flutter (20636): When the exception was thrown, this was the stack: I/flutter (20636): #0 Scaffold.of (package:flutter/src/material/scaffold.dart:1456:5) I/flutter (20636): #1 _CBandeiraState.build.<anonymous closure> (package:gerenciador/views/core/cartao/c_bandeira.dart:43:20) I/flutter (20636): #2 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:779:19) I/flutter (20636): #3 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:862:36) I/flutter (20636): #4 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24) I/flutter (20636): #5 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:504:11) I/flutter (20636): #6 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:282:5) I/flutter (20636): #7 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:217:7) I/flutter (20636): #8 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:475:9) I/flutter (20636): #9 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:76:12) I/flutter (20636): #10 PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:122:9) I/flutter (20636): #11 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:379:8) I/flutter (20636): #12 PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:120:18) I/flutter (20636): #13 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:106:7) I/flutter (20636): #14 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19) I/flutter (20636): #15 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22) I/flutter (20636): #16 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7) I/flutter (20636): #17 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7) I/flutter (20636): #18 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7) I/flutter (20636): #22 _invoke1 (dart:ui/hooks.dart:275:10) I/flutter (20636): #23 _dispatchPointerDataPacket (dart:ui/hooks.dart:184:5) I/flutter (20636): (elided 3 frames from dart:async) I/flutter (20636): I/flutter (20636): Handler: "onTap" I/flutter (20636): Recognizer: I/flutter (20636): TapGestureRecognizer#033d5 I/flutter (20636): ════════════════════════════════════════════════════════════════════════════════════════════════════Am I missing something to accomplish what I am trying to do? I started flutter just a few days ago so I wouldn't be surprised if I am doing this the wrong way.