Skip to content

Instantly share code, notes, and snippets.

@HansMuller
Last active February 8, 2022 20:05
Show Gist options
  • Save HansMuller/b947e76c34d941397989eaab537d45ca to your computer and use it in GitHub Desktop.
Save HansMuller/b947e76c34d941397989eaab537d45ca to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
class ABCModel extends InheritedModel<String> {
ABCModel({
Key key,
this.a,
this.b,
this.c,
Widget child,
}) : super(key: key, child: child);
final int a;
final int b;
final int c;
@override
bool updateShouldNotify(ABCModel old) {
return a != old.a || b != old.b || c != old.c;
}
@override
bool updateShouldNotifyDependent(ABCModel old, Set<String> fieldNames) {
return (a != old.a && fieldNames.contains('a'))
|| (b != old.b && fieldNames.contains('b'))
|| (c != old.c && fieldNames.contains('c'));
}
static ABCModel of(BuildContext context, { String fieldName }) {
return InheritedModel.inheritFrom<ABCModel>(context, aspect: fieldName);
}
}
class ShowABCField extends StatefulWidget {
ShowABCField({ Key key, this.fieldName }) : super(key: key);
final String fieldName;
_ShowABCFieldState createState() => new _ShowABCFieldState();
}
class _ShowABCFieldState extends State<ShowABCField> {
int _buildCount = 0;
@override
Widget build(BuildContext context) {
final ABCModel abc = ABCModel.of(context, fieldName: widget.fieldName);
final int value = widget.fieldName == 'a' ? abc.a : (widget.fieldName == 'b' ? abc.b : abc.c);
return new Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: new Text('${widget.fieldName} : $value [${_buildCount++}]', style: Theme.of(context).textTheme.title),
);
}
}
class ABCPage extends StatefulWidget {
@override
_ABCPageState createState() => new _ABCPageState();
}
class _ABCPageState extends State<ABCPage> {
int _a = 0;
int _b = 1;
int _c = 2;
@override
Widget build(BuildContext context) {
final Widget showA = new ShowABCField(fieldName: 'a');
final Widget showB = new ShowABCField(fieldName: 'b');
final Widget showC = new ShowABCField(fieldName: 'c');
// Unconditionally depends on the ABCModel
final Widget showABC = new Builder(
builder: (BuildContext context) {
final ABCModel abc = ABCModel.of(context);
return new Text('a: ${abc.a} b: ${abc.b} c: ${abc.c}', style: Theme.of(context).textTheme.title);
}
);
return new Scaffold(
body: new StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return new ABCModel(
a: _a,
b: _b,
c: _c,
child: new Center(
child: new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
showA,
showB,
showC,
const SizedBox(height: 24.0),
showABC,
const SizedBox(height: 24.0),
new RaisedButton(
child: const Text('Increment a'),
onPressed: () {
// Rebuilds the ABCModel which triggers a rebuild
// of showA because showA depends on the 'a' aspect
// of the ABCModel.
setState(() { _a += 1; });
},
),
new RaisedButton(
child: const Text('Increment b'),
onPressed: () {
// Rebuilds the ABCModel which triggers a rebuild
// of showB because showB depends on the 'b' aspect
// of the ABCModel.
setState(() { _b += 1; });
},
),
new RaisedButton(
child: const Text('Increment c'),
onPressed: () {
// Rebuilds the ABCModel which triggers a rebuild
// of showC because showC depends on the 'c' aspect
// of the ABCModel.
setState(() { _c += 1; });
},
),
],
),
),
);
},
),
);
}
}
void main() {
runApp(
new MaterialApp(
home: new ABCPage(),
),
);
}
@jifalops
Copy link

ezgif com-video-to-gif

@jifalops
Copy link

jifalops commented Oct 16, 2018

(Syntax highlighting (@HansMuller change filename to .dart))

import 'package:flutter/material.dart';

class ABCModel extends InheritedModel<String> {
  ABCModel({
    Key key,
    this.a,
    this.b,
    this.c,
    Widget child,
  }) : super(key: key, child: child);

  final int a;
  final int b;
  final int c;

  @override
  bool updateShouldNotify(ABCModel old) {
    return a != old.a || b != old.b || c != old.c;
  }

  @override
  bool updateShouldNotifyDependent(ABCModel old, Set<String> fieldNames) {
    return (a != old.a && fieldNames.contains('a'))
        || (b != old.b && fieldNames.contains('b'))
        || (c != old.c && fieldNames.contains('c'));
  }

  static ABCModel of(BuildContext context, { String fieldName }) {
    return InheritedModel.inheritFrom<ABCModel>(context, aspect: fieldName);
  }
}

class ShowABCField extends StatefulWidget {
  ShowABCField({ Key key, this.fieldName }) : super(key: key);

  final String fieldName;

  _ShowABCFieldState createState() => new _ShowABCFieldState();
}

class _ShowABCFieldState extends State<ShowABCField> {
  int _buildCount = 0;

  @override
  Widget build(BuildContext context) {
    final ABCModel abc = ABCModel.of(context, fieldName: widget.fieldName);
    final int value = widget.fieldName == 'a' ? abc.a : (widget.fieldName == 'b' ? abc.b : abc.c);
    return new Padding(
      padding: const EdgeInsets.symmetric(vertical: 8.0),
      child: new Text('${widget.fieldName} : $value  [${_buildCount++}]', style: Theme.of(context).textTheme.title),
    );
  }
}

class ABCPage extends StatefulWidget {
  @override
  _ABCPageState createState() => new _ABCPageState();
}

class _ABCPageState extends State<ABCPage> {
  int _a = 0;
  int _b = 1;
  int _c = 2;

  @override
  Widget build(BuildContext context) {
    final Widget showA = new ShowABCField(fieldName: 'a');
    final Widget showB = new ShowABCField(fieldName: 'b');
    final Widget showC = new ShowABCField(fieldName: 'c');

    // Unconditionally depends on the ABCModel
    final Widget showABC = new Builder(
      builder: (BuildContext context) {
        final ABCModel abc = ABCModel.of(context);
        return new Text('a: ${abc.a} b: ${abc.b} c: ${abc.c}', style: Theme.of(context).textTheme.title);
      }
    );

    return new Scaffold(
      body: new StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return new ABCModel(
            a: _a,
            b: _b,
            c: _c,
            child: new Center(
              child: new Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  showA,
                  showB,
                  showC,
                  const SizedBox(height: 24.0),
                  showABC,
                  const SizedBox(height: 24.0),
                  new RaisedButton(
                    child: const Text('Increment a'),
                    onPressed: () {
                      // Rebuilds the ABCModel which triggers a rebuild
                      // of showA because showA depends on the 'a' aspect
                      // of the ABCModel.
                      setState(() { _a += 1; });
                    },
                  ),
                  new RaisedButton(
                    child: const Text('Increment b'),
                    onPressed: () {
                      // Rebuilds the ABCModel which triggers a rebuild
                      // of showB because showB depends on the 'b' aspect
                      // of the ABCModel.
                      setState(() { _b += 1; });
                    },
                  ),
                  new RaisedButton(
                    child: const Text('Increment c'),
                    onPressed: () {
                      // Rebuilds the ABCModel which triggers a rebuild
                      // of showC because showC depends on the 'c' aspect
                      // of the ABCModel.
                      setState(() { _c += 1; });
                    },
                  ),
                ],
              ),
            ),
          );
        },
      ),
    );
  }
}

void main() {
  runApp(
    new MaterialApp(
      home: new ABCPage(),
    ),
  );
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment