diff --git a/lib/main.dart b/lib/main.dart index 94731618..186ce12b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,8 +4,10 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'package:dynamic_color/dynamic_color.dart'; +import 'package:hive/hive.dart'; import 'package:pilipala/common/widgets/custom_toast.dart'; import 'package:pilipala/http/init.dart'; +import 'package:pilipala/models/common/theme_type.dart'; import 'package:pilipala/pages/search/index.dart'; import 'package:pilipala/pages/video/detail/index.dart'; import 'package:pilipala/router/app_pages.dart'; @@ -33,19 +35,38 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { + Color brandColor = Colors.green; + Box setting = GStrorage.setting; + ThemeType currentThemeValue = ThemeType.values[setting + .get(SettingBoxKey.themeMode, defaultValue: ThemeType.system.code)]; return DynamicColorBuilder( - builder: ((lightDynamic, darkDynamic) { + builder: ((ColorScheme? lightDynamic, ColorScheme? darkDynamic) { + ColorScheme? lightColorScheme; + ColorScheme? darkColorScheme; + if (lightDynamic != null && darkDynamic != null) { + // dynamic取色成功 + lightColorScheme = lightDynamic.harmonized(); + darkColorScheme = darkDynamic.harmonized(); + } else { + // dynamic取色失败,采用品牌色 + lightColorScheme = ColorScheme.fromSeed( + seedColor: brandColor, + brightness: Brightness.light, + ); + darkColorScheme = ColorScheme.fromSeed( + seedColor: brandColor, + brightness: Brightness.dark, + ); + } // 图片缓存 // PaintingBinding.instance.imageCache.maximumSizeBytes = 1000 << 20; return GetMaterialApp( title: 'PiLiPaLa', theme: ThemeData( // fontFamily: 'HarmonyOS', - colorScheme: lightDynamic ?? - ColorScheme.fromSeed( - seedColor: Colors.green, - brightness: Brightness.light, - ), + colorScheme: currentThemeValue == ThemeType.dark + ? darkColorScheme + : lightColorScheme, useMaterial3: true, pageTransitionsTheme: const PageTransitionsTheme( builders: { @@ -57,11 +78,9 @@ class MyApp extends StatelessWidget { ), darkTheme: ThemeData( // fontFamily: 'HarmonyOS', - colorScheme: darkDynamic ?? - ColorScheme.fromSeed( - seedColor: Colors.green, - brightness: Brightness.dark, - ), + colorScheme: currentThemeValue == ThemeType.light + ? lightColorScheme + : darkColorScheme, useMaterial3: true, ), localizationsDelegates: const [ diff --git a/lib/models/common/theme_type.dart b/lib/models/common/theme_type.dart new file mode 100644 index 00000000..d2dac752 --- /dev/null +++ b/lib/models/common/theme_type.dart @@ -0,0 +1,13 @@ +enum ThemeType { + light, + dark, + system, +} + +extension ThemeTypeDesc on ThemeType { + String get description => ['浅色', '深色', '跟随系统'][index]; +} + +extension ThemeTypeCode on ThemeType { + int get code => [0, 1, 2][index]; +} diff --git a/lib/pages/mine/controller.dart b/lib/pages/mine/controller.dart index 6d515243..9562f488 100644 --- a/lib/pages/mine/controller.dart +++ b/lib/pages/mine/controller.dart @@ -1,6 +1,8 @@ +import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:hive/hive.dart'; import 'package:pilipala/http/user.dart'; +import 'package:pilipala/models/common/theme_type.dart'; import 'package:pilipala/models/user/info.dart'; import 'package:pilipala/models/user/stat.dart'; import 'package:pilipala/utils/storage.dart'; @@ -10,9 +12,11 @@ class MineController extends GetxController { Rx userInfo = UserInfoData().obs; // 用户状态 动态、关注、粉丝 Rx userStat = UserStat().obs; - Box user = GStrorage.user; RxBool userLogin = false.obs; + Box user = GStrorage.user; + Box setting = GStrorage.setting; Box userInfoCache = GStrorage.userInfo; + Rx themeType = ThemeType.system.obs; @override onInit() { @@ -21,6 +25,9 @@ class MineController extends GetxController { if (userInfoCache.get('userInfoCache') != null) { userInfo.value = userInfoCache.get('userInfoCache'); } + + themeType.value = ThemeType.values[setting.get(SettingBoxKey.themeMode, + defaultValue: ThemeType.system.code)]; } onLogin() async { @@ -90,4 +97,31 @@ class MineController extends GetxController { userLogin.value = false; // Get.find().resetLast(); } + + onChangeTheme() { + Brightness currentBrightness = + MediaQuery.of(Get.context!).platformBrightness; + ThemeType currentTheme = themeType.value; + switch (currentTheme) { + case ThemeType.dark: + setting.put(SettingBoxKey.themeMode, ThemeType.light.code); + themeType.value = ThemeType.light; + break; + case ThemeType.light: + setting.put(SettingBoxKey.themeMode, ThemeType.dark.code); + themeType.value = ThemeType.dark; + break; + case ThemeType.system: + // 判断当前的颜色模式 + if (currentBrightness == Brightness.light) { + setting.put(SettingBoxKey.themeMode, ThemeType.dark.code); + themeType.value = ThemeType.dark; + } else { + setting.put(SettingBoxKey.themeMode, ThemeType.light.code); + themeType.value = ThemeType.light; + } + break; + } + Get.forceAppUpdate(); + } } diff --git a/lib/pages/mine/view.dart b/lib/pages/mine/view.dart index 3cf560dc..f991c3a2 100644 --- a/lib/pages/mine/view.dart +++ b/lib/pages/mine/view.dart @@ -5,6 +5,8 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:pilipala/common/constants.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; +import 'package:pilipala/models/common/theme_type.dart'; +import 'package:pilipala/utils/storage.dart'; import 'controller.dart'; class MinePage extends StatelessWidget { @@ -24,13 +26,11 @@ class MinePage extends StatelessWidget { title: null, actions: [ IconButton( - onPressed: () { - Get.changeThemeMode(ThemeMode.dark); - }, + onPressed: () => mineController.onChangeTheme(), icon: Icon( - Get.theme == ThemeData.light() - ? CupertinoIcons.moon - : CupertinoIcons.sun_max, + mineController.themeType.value == ThemeType.dark + ? CupertinoIcons.sun_max + : CupertinoIcons.moon, size: 22, ), ), @@ -93,7 +93,7 @@ class MinePage extends StatelessWidget { src: _mineController.userInfo.value.face, width: 85, height: 85) - : Image.asset('assets/images/loading.png'), + : Image.asset('assets/images/noface.jpeg'), ), ), ), diff --git a/lib/pages/setting/controller.dart b/lib/pages/setting/controller.dart index 843d21d0..70405e4b 100644 --- a/lib/pages/setting/controller.dart +++ b/lib/pages/setting/controller.dart @@ -1,11 +1,9 @@ import 'package:get/get.dart'; import 'package:hive/hive.dart'; import 'package:pilipala/http/init.dart'; -import 'package:pilipala/pages/dynamics/index.dart'; +import 'package:pilipala/models/common/theme_type.dart'; import 'package:pilipala/pages/home/index.dart'; -import 'package:pilipala/pages/main/index.dart'; import 'package:pilipala/pages/mine/controller.dart'; -import 'package:pilipala/utils/data.dart'; import 'package:pilipala/utils/feed_back.dart'; import 'package:pilipala/utils/storage.dart'; @@ -17,6 +15,7 @@ class SettingController extends GetxController { RxBool userLogin = false.obs; RxBool feedBackEnable = false.obs; RxInt picQuality = 10.obs; + Rx themeType = ThemeType.system.obs; @override void onInit() { @@ -26,6 +25,8 @@ class SettingController extends GetxController { setting.get(SettingBoxKey.feedBackEnable, defaultValue: false); picQuality.value = setting.get(SettingBoxKey.defaultPicQa, defaultValue: 10); + themeType.value = ThemeType.values[setting.get(SettingBoxKey.themeMode, + defaultValue: ThemeType.system.code)]; } loginOut() async { diff --git a/lib/pages/setting/style_setting.dart b/lib/pages/setting/style_setting.dart index a986d1ff..397edbbf 100644 --- a/lib/pages/setting/style_setting.dart +++ b/lib/pages/setting/style_setting.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:hive/hive.dart'; +import 'package:pilipala/models/common/theme_type.dart'; import 'package:pilipala/utils/storage.dart'; import 'controller.dart'; @@ -16,11 +17,13 @@ class _StyleSettingState extends State { final SettingController settingController = Get.put(SettingController()); Box setting = GStrorage.setting; late int picQuality; + late ThemeType _tempThemeValue; @override void initState() { super.initState(); picQuality = setting.get(SettingBoxKey.defaultPicQa, defaultValue: 10); + _tempThemeValue = settingController.themeType.value; } @override @@ -74,7 +77,7 @@ class _StyleSettingState extends State { final SettingController settingController = Get.put(SettingController()); return AlertDialog( - title: Text('图片清晰度 - $picQuality%', style: titleStyle), + title: const Text('图片质量'), contentPadding: const EdgeInsets.only( top: 20, left: 8, right: 8, bottom: 8), content: SizedBox( @@ -94,7 +97,11 @@ class _StyleSettingState extends State { actions: [ TextButton( onPressed: () => Get.back(), - child: const Text('取消')), + child: Text('取消', + style: TextStyle( + color: Theme.of(context) + .colorScheme + .outline))), TextButton( onPressed: () { setting.put( @@ -120,6 +127,63 @@ class _StyleSettingState extends State { ), ), ), + ListTile( + dense: false, + onTap: () { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: const Text('主题模式'), + contentPadding: const EdgeInsets.fromLTRB(0, 12, 0, 12), + content: StatefulBuilder( + builder: (context, StateSetter setState) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + for (var i in ThemeType.values) ...[ + RadioListTile( + value: i, + title: Text(i.description, style: titleStyle), + groupValue: _tempThemeValue, + onChanged: (ThemeType? value) { + setState(() { + _tempThemeValue = i; + }); + }, + ), + ] + ], + ); + }), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text( + '取消', + style: TextStyle( + color: Theme.of(context).colorScheme.outline), + )), + TextButton( + onPressed: () { + settingController.themeType.value = _tempThemeValue; + setting.put( + SettingBoxKey.themeMode, _tempThemeValue.code); + Get.forceAppUpdate(); + Get.back(); + }, + child: const Text('确定')) + ], + ); + }, + ); + }, + title: Text('主题模式', style: titleStyle), + subtitle: Obx(() => Text( + '当前模式:${settingController.themeType.value.description}', + style: subTitleStyle)), + trailing: const Icon(Icons.arrow_right_alt_outlined), + ), ], ), );