Skip to content

Instantly share code, notes, and snippets.

@HansMuller
Created August 3, 2018 23:42
Show Gist options
  • Save HansMuller/f0670f01ff791249a4504ae104e867e8 to your computer and use it in GitHub Desktop.
Save HansMuller/f0670f01ff791249a4504ae104e867e8 to your computer and use it in GitHub Desktop.
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