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