Created
August 3, 2018 23:42
-
-
Save HansMuller/f0670f01ff791249a4504ae104e867e8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
// This class is a simulacrum of an internally complex opaque data object, | |
// whose values can only be retrieved via path lookup. | |
class IntegerTree { | |
int _a = 0; | |
int _b = 1; | |
int _c = 2; | |
int valueOf(String path) => path == 'a' ? _a : (path == 'b' ? _b : _c); | |
} | |
// Dependents identify the path they depend on. The IntegerModel records | |
// both the path and the path's current value. See IntegerModel.getDependencyFor(). | |
class PathDependency { | |
PathDependency(this.path, this.value); | |
final String path; | |
final int value; | |
} | |
// This model only rebuilds dependents when the value of the paths they | |
// depend on changes. | |
class IntegerModel extends InheritedModel<PathDependency> { | |
const IntegerModel({ | |
Key key, | |
this.integerTree, | |
Widget child | |
}) : super(key: key, child: child); | |
final IntegerTree integerTree; | |
@override | |
PathDependency getDependencyFor(dynamic aspect) { | |
final String path = aspect; | |
return new PathDependency(path, integerTree.valueOf(path)); | |
} | |
@override | |
bool updateShouldNotifyDependent(IntegerModel old, Set<PathDependency> dependencies ) { | |
for (PathDependency dependency in dependencies) { | |
if (dependency.value != integerTree.valueOf(dependency.path)) | |
return true; | |
} | |
return false; | |
} | |
static IntegerTree of(BuildContext context, { String path }) { | |
final IntegerModel integerModel = context.inheritFromWidgetOfExactType(IntegerModel, aspect: path); | |
return integerModel.integerTree; | |
} | |
} | |
class ShowIntegerPath extends StatefulWidget { | |
ShowIntegerPath({ Key key, this.path }) : super(key: key); | |
final String path; | |
_ShowIntegerPathState createState() => new _ShowIntegerPathState(); | |
} | |
class _ShowIntegerPathState extends State<ShowIntegerPath> { | |
int _buildCount = 0; | |
@override | |
Widget build(BuildContext context) { | |
final IntegerTree integerTree = IntegerModel.of(context, path: widget.path); | |
final int value = integerTree.valueOf(widget.path); | |
return new Padding( | |
padding: const EdgeInsets.symmetric(vertical: 8.0), | |
child: new Text('${widget.path} : $value [${_buildCount++}]', style: Theme.of(context).textTheme.title), | |
); | |
} | |
} | |
class IntegerPage extends StatefulWidget { | |
@override | |
_IntegerPageState createState() => new _IntegerPageState(); | |
} | |
class _IntegerPageState extends State<IntegerPage> { | |
final IntegerTree _integerTree = new IntegerTree(); | |
@override | |
Widget build(BuildContext context) { | |
final Widget showA = new ShowIntegerPath(path: 'a'); | |
final Widget showB = new ShowIntegerPath(path: 'b'); | |
final Widget showC = new ShowIntegerPath(path: 'c'); | |
return new Scaffold( | |
appBar: new AppBar(title: const Text('InheritedModel')), | |
body: new StatefulBuilder( | |
builder: (BuildContext context, StateSetter setState) { | |
return new IntegerModel( | |
integerTree: _integerTree, | |
child: new Center( | |
child: new Column( | |
mainAxisSize: MainAxisSize.min, | |
children: <Widget>[ | |
showA, | |
showB, | |
showC, | |
const SizedBox(height: 24.0), | |
new RaisedButton( | |
child: const Text('Increment a'), | |
onPressed: () { | |
setState(() { | |
_integerTree._a += 1; | |
}); | |
}, | |
), | |
new RaisedButton( | |
child: const Text('Increment b'), | |
onPressed: () { | |
setState(() { | |
_integerTree._b += 1; | |
}); | |
}, | |
), | |
new RaisedButton( | |
child: const Text('Increment c'), | |
onPressed: () { | |
setState(() { | |
_integerTree._c += 1; | |
}); | |
}, | |
), | |
], | |
), | |
), | |
); | |
}, | |
), | |
); | |
} | |
} | |
void main() { | |
runApp( | |
new MaterialApp( | |
home: new IntegerPage(), | |
), | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment