import 'dart:async'; import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { ThemeMode themeMode = ThemeMode.light; @override Widget build(BuildContext context) { return MaterialApp( home: MyThemeWidget( onChangeTheme: changeTheme, themeMode: themeMode, child: RootWidget(), ), darkTheme: ThemeData.dark().copyWith( brightness: Brightness.dark, ), themeMode: ThemeMode.system, ); } void changeTheme(ThemeMode themeMode) { setState(() { this.themeMode = themeMode; }); } } class RootWidget extends StatefulWidget { const RootWidget({super.key}); @override State<RootWidget> createState() => _RootWidgetState(); } class _RootWidgetState extends State<RootWidget> { int _count = 0; @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: () { setState(() { _count++; }); }, child: Text('update widget'), ), Home( count: _count, ), ], )), ); } } class Home extends StatefulWidget { Home({super.key, required this.count}); final int count; @override State<Home> createState() => _HomeState(); } class _HomeState extends State<Home> { int _count = 0; late Timer _timer; @override void initState() { _timer = Timer.periodic(Duration(seconds: 1), (timer) { if (mounted) { setState(() { _count++; }); } }); super.initState(); } @override void didChangeDependencies() { print('flutter lifecycle is called didchange dependency'); super.didChangeDependencies(); } @override void didUpdateWidget(covariant Home oldWidget) { super.didUpdateWidget(oldWidget); print('old count is ${oldWidget.count} new count ${widget.count}'); } @override Widget build(BuildContext context) { final MediaQueryData mediaQuery = MediaQuery.of(context); final String systemTheme = mediaQuery.platformBrightness == Brightness.dark ? "Dark Theme" : "Light Theme"; final MyThemeWidget myThemeWidget = MyThemeWidget.of(context); final String theme = myThemeWidget.themeMode == ThemeMode.dark ? "Dark Theme" : "Light Theme"; return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text("device theme is $systemTheme"), Divider(), Text( "widgth is ${mediaQuery.size.width.toInt()} height is ${mediaQuery.size.height.toInt()}"), Divider(), Text("Current theme is $theme"), Text( _count.toString(), style: TextStyle(fontSize: 34), ), FloatingActionButton( onPressed: () { setState(() { _count++; }); }, child: Icon(Icons.add), ), SwitchListTile( title: Text("Dark Theme"), value: myThemeWidget.themeMode == ThemeMode.dark, onChanged: (isDark) { ThemeMode themeMode = isDark ? ThemeMode.dark : ThemeMode.light; myThemeWidget.onChangeTheme(themeMode); }, ), ], ), ); } @override void deactivate() { super.deactivate(); } @override void dispose() { print('flutter lifecycle is called destoryed '); super.dispose(); if (_timer.isActive) { _timer.cancel(); } } } class MyThemeWidget extends InheritedWidget { const MyThemeWidget({ required super.child, required this.themeMode, required this.onChangeTheme, }); final ThemeMode themeMode; final Function(ThemeMode) onChangeTheme; static MyThemeWidget of(BuildContext context) { return context.dependOnInheritedWidgetOfExactType<MyThemeWidget>()!; } @override bool updateShouldNotify(covariant MyThemeWidget oldWidget) { return oldWidget.themeMode != themeMode; } }