import 'package:flutter/material.dart';
/// import 'package:shared_preferences/shared_preferences.dart';
/// Flutter 动态修改应用主题
///
///
/// [特别说明]
///
/// 因为CodePen不支持引入第三方包,所以此处注释了SharedPreferences相关的内容(SharedPreferences可以使应用重启后设置依然生效).
/// 安装SharedPreferences: https://pub.dev/packages/shared_preferences
///
/// [原理]
///
/// 在MyApp中传递给SettingApp一个回调方法,如果SettingApp需要更新MyApp中的任意值,直接调用此方法即可(目前通过Map<String,Object>传递值,因为无法动态调用setState).
///
/// @version 2020--05-31
/// @author prd([email protected])(bckf.cn)
///
/// Flutter dynamically modify the application theme
///
///
/// [Special Note]
///
/// Because CodePen does not support the introduction of third-party packages, the contents related to SharedPreferences are annotated here (SharedPreferences can make the settings still effective after the application restarts).
/// Install SharedPreferences: https://pub.dev/packages/shared_preferences
///
/// [Principle]
///
/// Pass a callback method to SettingApp in MyApp. If SettingApp needs to update any value in MyApp, just call this method (currently pass the value through Map <String, Object> because setState cannot be called dynamically).
///
/// @version 2020--05-31
/// @author prd ([email protected])(bckf.cn)
void main() {
runApp(MyApp() );
}
typedef MainStateUpdateCall = void Function(Map<String,Object> map);
class MyApp extends StatefulWidget {
const MyApp();
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _darkTheme = false;
/// final _ThemeKey = "THEME";
/// 外部接口调用此方法修改本类的属性.
///
/// 可以通过传递在map中传递值,来修改系统属性.
/// 使用可以参考:
///
/// The external interface calls this method to modify the properties of this class.
///
/// You can modify system properties by passing values in the map.
/// Use can refer to:
///
/// [_SettingAppState]的setAndReloadTheme方法.
void mainStateUpdateMethod(Map<String,Object> map) {
map.forEach((key, value) {
setState((){
switch(key){
case "_darkTheme":
_darkTheme=value;
break;
}
});
});
}
@override
void initState() {
super.initState();
initTheme();
}
/// CodePen cannot introduce third-party packages, so comment the code below.
///
///
void initTheme() async {
// final prefs = await SharedPreferences.getInstance();
// bool tempTheme = false;
// if (prefs.containsKey(_ThemeKey)) {
// tempTheme = prefs.getBool(_ThemeKey);
// }
// setState(() {
// _darkTheme = tempTheme;
// });
}
@override
Widget build(BuildContext context) {
return MaterialApp(
theme:_darkTheme ? ThemeData.dark() : ThemeData.light(),
home: SettingApp(mainStateUpdateCall: mainStateUpdateMethod,),
);
}
}
/// Setting.
///
///
class SettingApp extends StatefulWidget {
const SettingApp({this.mainStateUpdateCall});
final MainStateUpdateCall mainStateUpdateCall;
@override
_SettingAppState createState() => _SettingAppState();
}
class _SettingAppState extends State<SettingApp> {
bool _darkTheme = false;
/// final _themeKey = "THEME";
var resData = [];
@override
void initState() {
super.initState();
initSetting();
}
void initSetting() async {
/// final prefs = await SharedPreferences.getInstance();
/// bool tempTheme = false;
///if (prefs.containsKey(_ThemeKey)) {
/// tempTheme = prefs.getBool(_ThemeKey);
/// }
// setState(() {
// _darkTheme = tempTheme;
// });
var tempResData = [
Card(
child: ListTile(
title: Text('dark'),
trailing: Switch(
value: _darkTheme,
onChanged: (value) {
setAndReloadTheme(value);
/// Call this method again to generate the list-so that the displayed value is correct.
/// 重新调用此方法生成列表-以使显示的值正确.
initSetting();
}),
),
),
Text("Support: bckf.cn / [email protected]")
];
setState(() {
resData = tempResData;
});
}
/// 保存设置和重新加载主题.
/// Save the settings and reload the theme.
///
void setAndReloadTheme(bool value) async {
/// final prefs = await SharedPreferences.getInstance();
/// prefs.setBool(_ThemeKey, value);
///
///
/// 调用全局更换.
/// Call global replacement.
setState(() {
_darkTheme = value;
});
print(value);
print(_darkTheme);
if (widget.mainStateUpdateCall != null) {
var paramMap={"_darkTheme":value};
widget.mainStateUpdateCall(paramMap);
}
}
@override
Widget build(BuildContext context) {
var listView = ListView.separated(
padding: const EdgeInsets.all(2),
itemCount: resData.length,
itemBuilder: (BuildContext itemBuildContext, int index) {
return Padding(
padding: EdgeInsets.all(5.0),
child: resData[index],
);
},
separatorBuilder: (BuildContext context, int index) => Divider(
color: Theme.of(context).dividerColor,
),
);
return Scaffold(
appBar: AppBar(title: Text("Flutter Dynamic Update App Theme")),
body: listView,
);
}
}
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.