Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- This version of the example adds a static Model method for updating the
- ModelBinding's current model value:
- ```
- Model.update(context, newModel);
- ```
- This substantially reduces the plumbing required for widgets that need to
- changes the app's model. Instead of passing down a callback that rebuilds the
- ModelBinding, any widget can update the ModelBinding's current state directly.
- The stateless ViewController now handles a button press like this:
- ```
- onPressed: () {
- final Model model = Model.of(context);
- Model.update(context, Model(value: model.value + 1));
- }
- ```
- The implementation of this feature is a little tricky. ModelBinding is now
- a stateful widget that tracks the current Model value. ModelBinding
- builds an _ModelBindingScope InheritedWidget child that has pointer to the
- State<ModelBinding> - an _ModelBindingState; essentially to its stateful widget
- (ModelBinding) parent. To update change ModelBinding's current Model value,
- we rebuild the ModelBinding with setState().
- */
- import 'package:flutter/material.dart';
- class Model {
- const Model({ this.value = 0 });
- final int value;
- @override
- bool operator ==(Object other) {
- if (identical(this, other))
- return true;
- if (other.runtimeType != runtimeType)
- return false;
- final Model otherModel = other;
- return otherModel.value == value;
- }
- @override
- int get hashCode => value.hashCode;
- static Model of(BuildContext context) {
- final _ModelBindingScope scope = context.inheritFromWidgetOfExactType(_ModelBindingScope);
- return scope.modelBindingState.currentModel;
- }
- static void update(BuildContext context, Model newModel) {
- final _ModelBindingScope scope = context.inheritFromWidgetOfExactType(_ModelBindingScope);
- scope.modelBindingState.updateModel(newModel);
- }
- }
- class _ModelBindingScope extends InheritedWidget {
- _ModelBindingScope({
- Key key,
- @required this.modelBindingState,
- Widget child,
- }) : assert(modelBindingState != null), super(key: key, child: child);
- final _ModelBindingState modelBindingState;
- @override
- bool updateShouldNotify(_ModelBindingScope oldWidget) => true;
- }
- class ModelBinding extends StatefulWidget {
- ModelBinding({
- Key key,
- this.initialModel = const Model(),
- this.child,
- }) : assert(initialModel != null), super(key: key);
- final Model initialModel;
- final Widget child;
- _ModelBindingState createState() => _ModelBindingState();
- }
- class _ModelBindingState extends State<ModelBinding> {
- Model currentModel;
- @override
- void initState() {
- super.initState();
- currentModel = widget.initialModel;
- }
- void updateModel(Model newModel) {
- if (newModel != currentModel) {
- setState(() {
- currentModel = newModel;
- });
- }
- }
- @override
- Widget build(BuildContext context) {
- return _ModelBindingScope(
- modelBindingState: this,
- child: widget.child,
- );
- }
- }
- class ViewController extends StatelessWidget {
- @override
- Widget build(BuildContext context) {
- return RaisedButton(
- onPressed: () {
- final Model model = Model.of(context);
- Model.update(context, Model(value: model.value + 1));
- },
- child: Text('Hello World ${Model.of(context).value}'),
- );
- }
- }
- class App extends StatelessWidget {
- @override
- Widget build(BuildContext context) {
- return MaterialApp(
- home: ModelBinding(
- initialModel: const Model(),
- child: Scaffold(
- body: Center(
- child: ViewController(),
- ),
- ),
- ),
- );
- }
- }
- void main() {
- runApp(App());
- }
Add Comment
Please, Sign In to add comment