Flutter Widget 101 Part 5 (Snackbars, Context, Builder and Key)
1. Aim
Through Snackbar, understand Context and how to use builder to access any context of a widget.
2.Snackbar
Code from Codelab
If you use Scaffold.of(context), there will be Context Error
Global Key
Expensive process
Allows element to be moved around (Unique global key in tree) without losing the state (Able to retrieve state).
Usage of Global Key
As Global Key is expensive. Use it only when it matters e.g. Validation of Form
Solution 2 (Identifier through Global Key)
Flutter Links:
If you use Scaffold.of(context), there will be Context Error
"Scaffold.of() called with a context that does not contain a Scaffold"
import 'package:flutter/material.dart'; void main() { runApp(new MaterialApp(home: new SnackApp())); } class SnackApp extends StatefulWidget { @override _SnackAppState createState() => _SnackAppState(); } class _SnackAppState extends State<SnackApp> { @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text("Snackbar exercise"), ), body: new Center( child: new RaisedButton( onPressed: (){ final snackBar = SnackBar(content: Text('Yay! A SnackBar!')); Scaffold.of(context).showSnackBar(snackBar); }, child: new Text("Show Snackbar"), ), ), ); } }
This is because thecontext
is of the parent widget that instantiatedScaffold
. Not thecontext
of a child ofScaffold.
Scaffold is not created yet.
Solution 1. Use Builder. 3.Builder
What is a builder A platonic (simplest possible thing of that kind) widget that calls a closure (lambda/anonymous function) to obtain its child widget. Widget and ContextIn the Flutter framework, every widget has a build method that accepts a BuildContext parameter:Widget build ( BuildContext context ) { ... }This context object is passed to the widget's build function automatically by the framework. Hence there is no reason for any widget to have a constructor or function (aside from build) that would need to accept a context parameter.Thus you would not be able to pass a specific context object to a child.You cannot call build() and pass your own context object manually without calling the build function twice (Your manual call and automatic call by the framework).Thus you would not be able to pass a specific context object to a child.You cannot call build() and pass your own context object manually without calling the build function twice (Your manual call and automatic call by the framework).Purpose of Builder classSo, how can we pass a specific context object?Use Builder class to build and return child widgets. This will pass a specific context object down to its children. The Builder class is basically your own build function that you setup.How?
Builder gives Child (Snackbar) access to/pass context of Parent (Scaffold) widget
Builder class constructor:Builder({Key key, @required WidgetBuilder builder })creates a widget by delegating its build to the callback function passed through its constructor.
- Contains a BuildContext context parameter
- Builds and returns child widget(s) based on that context passed.
--------------------------------
Solution 1 (Passing Context via Builder)
import 'package:flutter/material.dart'; void main() { runApp(new MaterialApp(home: new SnackApp())); } class SnackApp extends StatefulWidget { @override _SnackAppState createState() => _SnackAppState(); } class _SnackAppState extends State<SnackApp> { @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text("Snackbar exercise"), ), body: Builder(builder: (context){ return new Center( child: new RaisedButton( onPressed: (){ final snackBar = SnackBar(content: Text('Yay! A SnackBar!')); Scaffold.of(context).showSnackBar(snackBar); }, child: new Text("Show Snackbar"), ), ); }), ); } }
4. Key
What is a Key?
A new widget will only be used to update an existing element if its key is the same as the key of the current widget associated with the element.
Usage of Key
Control matching of widgets by framework during rebuilds.
Flutter matches widgets according to runtimeType, key and order of appearance.
Most useful in widgets that build many instances of the same type of widget. E.g. ShoppingList widget, builds many ShoppingListItem instances to fit screen.
Type of Keys
- Key
- GlobalKey
- ValueKey
- ObjectKey (e.g. of usage)
- UniqueKey
Expensive process
Allows element to be moved around (Unique global key in tree) without losing the state (Able to retrieve state).
Usage of Global Key
As Global Key is expensive. Use it only when it matters e.g. Validation of Form
Solution 2 (Identifier through Global Key)
import 'package:flutter/material.dart'; void main() { runApp(new MaterialApp(home: new SnackApp())); } class SnackApp extends StatefulWidget { @override _SnackAppState createState() => _SnackAppState(); } class _SnackAppState extends State<SnackApp> { final GlobalKey<ScaffoldState> _skey1 = GlobalKey<ScaffoldState>(); void snackm(){ _skey1.currentState.showSnackBar(SnackBar(content: Text('Yay! A SnackBar!'))); } @override Widget build(BuildContext context) { return new Scaffold( key: _skey1, appBar: new AppBar( title: new Text("Snackbar exercise"), ), body: Builder(builder: (context){ return new Center( child: new RaisedButton( onPressed: (){ //snackm(); _skey1.currentState.showSnackBar(SnackBar(content: Text('Yay! A SnackBar!'))); }, child: new Text("Show Snackbar"), ), ); }), ); } }
Flutter Links:
Comments
Post a Comment