Created
September 13, 2020 16:27
-
-
Save rodydavis/ace4be2b58108f938567824b1e7cf4d7 to your computer and use it in GitHub Desktop.
Inherited Widget + Notifications
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'; | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
debugShowCheckedModeBanner: false, | |
title: 'Flutter Demo', | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
visualDensity: VisualDensity.adaptivePlatformDensity, | |
), | |
home: MyHomePage(title: 'Flutter Demo Home Page'), | |
); | |
} | |
} | |
class MyHomePage extends StatefulWidget { | |
MyHomePage({Key key, this.title}) : super(key: key); | |
final String title; | |
@override | |
_MyHomePageState createState() => _MyHomePageState(); | |
} | |
class _MyHomePageState extends State<MyHomePage> { | |
final model = CounterModel(); | |
@override | |
Widget build(BuildContext context) { | |
return Model<CounterModel>( | |
value: model, | |
child: NotificationListener<CounterUpdate>( | |
onNotification: (notification) { | |
if (mounted) | |
setState(() { | |
model.value = notification.value; | |
}); | |
return true; | |
}, | |
child: Scaffold( | |
appBar: AppBar( | |
title: Text(widget.title), | |
), | |
body: CounterDisplay(), | |
floatingActionButton: CounterActions(), | |
), | |
), | |
); | |
} | |
} | |
class CounterActions extends StatelessWidget { | |
const CounterActions({ | |
Key key, | |
}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
final model = Model.of<CounterModel>(context); | |
return FloatingActionButton( | |
onPressed: () => CounterUpdate(model.value + 1)..dispatch(context), | |
tooltip: 'Increment', | |
child: Icon(Icons.add), | |
); | |
} | |
} | |
class CounterDisplay extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
final model = Model.of<CounterModel>(context); | |
return Center( | |
child: Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: <Widget>[ | |
Text( | |
'You have pushed the button this many times:', | |
), | |
Text( | |
'${model.value}', | |
style: Theme.of(context).textTheme.headline4, | |
), | |
], | |
), | |
); | |
} | |
} | |
class CounterUpdate extends Notification { | |
final int value; | |
CounterUpdate(this.value); | |
} | |
class CounterModel { | |
int value = 0; | |
} | |
class Model<T> extends InheritedWidget { | |
Model({ | |
Key key, | |
@required this.value, | |
@required this.child, | |
}) : super(key: key, child: child); | |
final Widget child; | |
final T value; | |
static T of<T>(BuildContext context) { | |
return context.dependOnInheritedWidgetOfExactType<Model<T>>()?.value; | |
} | |
@override | |
bool updateShouldNotify(Model oldWidget) { | |
return oldWidget != this; | |
} | |
@override | |
bool operator ==(Object o) { | |
if (identical(this, o)) return true; | |
return o is Model && o.child == child && o.value == value; | |
} | |
@override | |
int get hashCode => child.hashCode ^ value.hashCode; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment