Skip to content

Instantly share code, notes, and snippets.

@rrousselGit
Created July 19, 2020 09:07
Show Gist options
  • Save rrousselGit/a869b21a2ebd2466b876a5997c9cf3f1 to your computer and use it in GitHub Desktop.
Save rrousselGit/a869b21a2ebd2466b876a5997c9cf3f1 to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
// This example showcases how extracting widgets into StatelessWidgets
// instead of functions can improve performances, by rebuilding
// only what needs to update when the state changes
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(context) {
return Counter(
count: Count(),
child: MaterialApp(
home: Home(),
),
);
}
}
class Count extends ValueNotifier<int> {
Count() : super(0);
}
class Counter extends InheritedNotifier {
Counter({
Key key,
this.count,
Widget child,
}) : super(key: key, child: child, notifier: count);
final Count count;
static Count of(BuildContext context, {bool listen = true}) {
if (listen) {
return context.dependOnInheritedWidgetOfExactType<Counter>().count;
} else {
final Counter counter =
context.getElementForInheritedWidgetOfExactType<Counter>().widget;
return counter.count;
}
}
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('Home build');
return Scaffold(
body: Center(
// By extracting Title in a StatelessWidget, Home doesn't rebuild when the counter changes
child: Title(),
// Uncommenting this code causes Home to rebuild when the counter changes
// child: title(context)
),
floatingActionButton: FloatingActionButton(
onPressed: () => Counter.of(context, listen: false).value++,
child: Icon(Icons.add),
),
);
}
}
class Title extends StatelessWidget {
Widget build(context) {
print('build Title');
return Text('Count ${Counter.of(context).value}');
}
}
Widget title(context) {
print('build Title');
return Text('Count ${Counter.of(context).value}');
}
@craiglabenz
Copy link

This updated code fixes a few Null Safety issues on DartPad. Thanks for providing this!

import 'package:flutter/material.dart';

// This example showcases how extracting widgets into StatelessWidgets
// instead of functions can improve performances, by rebuilding
// only what needs to update when the state changes

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(context) {
    return Counter(
      count: Count(),
      child: MaterialApp(
        home: Home(),
      ),
    );
  }
}

class Count extends ValueNotifier<int> {
  Count() : super(0);
}

class Counter extends InheritedNotifier {
  const Counter({
    Key? key,
    required this.count,
    required Widget child,
  }) : super(key: key, child: child, notifier: count);

  final Count count;

  static Count of(BuildContext context, {bool listen = true}) {
    if (listen) {
      return context.dependOnInheritedWidgetOfExactType<Counter>()!.count;
    } else {
      final Counter counter =
          context.getElementForInheritedWidgetOfExactType<Counter>()!.widget as Counter;
      return counter.count;
    }
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print('Home build');
    return Scaffold(
      body: Center(
        // By extracting Title in a StatelessWidget, Home doesn't rebuild when the counter changes
        child: Title(),
        // Uncommenting this code causes Home to rebuild when the counter changes
        // child: title(context)
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => Counter.of(context, listen: false).value++,
        child: const Icon(Icons.add),
      ),
    );
  }
}

class Title extends StatelessWidget {
  @override
  Widget build(context) {
    print('build Title');
    return Text('Count ${Counter.of(context).value}');
  }
}

Widget title(context) {
  print('build Title');
  return Text('Count ${Counter.of(context).value}');
}

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