import 'package:flutter/material.dart'; class _AppModelScope extends InheritedWidget { const _AppModelScope({ Key key, this.appModelState, Widget child, }) : super(key: key, child: child); final _AppModelState appModelState; @override bool updateShouldNotify(_AppModelScope oldWidget) => true; } class AppModel extends StatefulWidget { AppModel({ Key key, @required this.initialState, this.child, }) : assert(initialState != null), super(key: key); final T initialState; final Widget child; _AppModelState createState() => _AppModelState(); static _typeOf() => T; static T of(BuildContext context) { final Type appModelScopeType = _typeOf<_AppModelScope>(); final _AppModelScope scope = context.inheritFromWidgetOfExactType(appModelScopeType); return scope.appModelState.currentState; } static void update(BuildContext context, T newState) { final Type appModelScopeType = _typeOf<_AppModelScope>(); final _AppModelScope scope = context.inheritFromWidgetOfExactType(appModelScopeType); scope.appModelState.updateState(newState); } } class _AppModelState extends State> { @override void initState() { super.initState(); currentState = widget.initialState; } T currentState; void updateState(T newState) { if (newState != currentState) { setState(() { currentState = newState; }); } } @override Widget build(BuildContext context) { return _AppModelScope( appModelState: this, child: widget.child, ); } }