Guest User

Untitled

a guest
Dec 15th, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.52 KB | None | 0 0
  1. /*
  2.  
  3. This version of the example adds a static Model method for updating the
  4. ModelBinding's current model value:
  5.  
  6. ```
  7. Model.update(context, newModel);
  8. ```
  9.  
  10. This substantially reduces the plumbing required for widgets that need to
  11. changes the app's model. Instead of passing down a callback that rebuilds the
  12. ModelBinding, any widget can update the ModelBinding's current state directly.
  13.  
  14. The stateless ViewController now handles a button press like this:
  15.  
  16. ```
  17. onPressed: () {
  18. final Model model = Model.of(context);
  19. Model.update(context, Model(value: model.value + 1));
  20. }
  21. ```
  22.  
  23. The implementation of this feature is a little tricky. ModelBinding is now
  24. a stateful widget that tracks the current Model value. ModelBinding
  25. builds an _ModelBindingScope InheritedWidget child that has pointer to the
  26. State<ModelBinding> - an _ModelBindingState; essentially to its stateful widget
  27. (ModelBinding) parent. To update change ModelBinding's current Model value,
  28. we rebuild the ModelBinding with setState().
  29.  
  30. */
  31.  
  32. import 'package:flutter/material.dart';
  33.  
  34. class Model {
  35. const Model({ this.value = 0 });
  36.  
  37. final int value;
  38.  
  39. @override
  40. bool operator ==(Object other) {
  41. if (identical(this, other))
  42. return true;
  43. if (other.runtimeType != runtimeType)
  44. return false;
  45. final Model otherModel = other;
  46. return otherModel.value == value;
  47. }
  48.  
  49. @override
  50. int get hashCode => value.hashCode;
  51.  
  52. static Model of(BuildContext context) {
  53. final _ModelBindingScope scope = context.inheritFromWidgetOfExactType(_ModelBindingScope);
  54. return scope.modelBindingState.currentModel;
  55. }
  56.  
  57. static void update(BuildContext context, Model newModel) {
  58. final _ModelBindingScope scope = context.inheritFromWidgetOfExactType(_ModelBindingScope);
  59. scope.modelBindingState.updateModel(newModel);
  60. }
  61. }
  62.  
  63. class _ModelBindingScope extends InheritedWidget {
  64. _ModelBindingScope({
  65. Key key,
  66. @required this.modelBindingState,
  67. Widget child,
  68. }) : assert(modelBindingState != null), super(key: key, child: child);
  69.  
  70. final _ModelBindingState modelBindingState;
  71.  
  72. @override
  73. bool updateShouldNotify(_ModelBindingScope oldWidget) => true;
  74. }
  75.  
  76. class ModelBinding extends StatefulWidget {
  77. ModelBinding({
  78. Key key,
  79. this.initialModel = const Model(),
  80. this.child,
  81. }) : assert(initialModel != null), super(key: key);
  82.  
  83. final Model initialModel;
  84. final Widget child;
  85.  
  86. _ModelBindingState createState() => _ModelBindingState();
  87. }
  88.  
  89. class _ModelBindingState extends State<ModelBinding> {
  90. Model currentModel;
  91.  
  92. @override
  93. void initState() {
  94. super.initState();
  95. currentModel = widget.initialModel;
  96. }
  97.  
  98. void updateModel(Model newModel) {
  99. if (newModel != currentModel) {
  100. setState(() {
  101. currentModel = newModel;
  102. });
  103. }
  104. }
  105.  
  106. @override
  107. Widget build(BuildContext context) {
  108. return _ModelBindingScope(
  109. modelBindingState: this,
  110. child: widget.child,
  111. );
  112. }
  113. }
  114.  
  115. class ViewController extends StatelessWidget {
  116. @override
  117. Widget build(BuildContext context) {
  118. return RaisedButton(
  119. onPressed: () {
  120. final Model model = Model.of(context);
  121. Model.update(context, Model(value: model.value + 1));
  122. },
  123. child: Text('Hello World ${Model.of(context).value}'),
  124. );
  125. }
  126. }
  127.  
  128. class App extends StatelessWidget {
  129. @override
  130. Widget build(BuildContext context) {
  131. return MaterialApp(
  132. home: ModelBinding(
  133. initialModel: const Model(),
  134. child: Scaffold(
  135. body: Center(
  136. child: ViewController(),
  137. ),
  138. ),
  139. ),
  140. );
  141. }
  142. }
  143.  
  144. void main() {
  145. runApp(App());
  146. }
Add Comment
Please, Sign In to add comment