From a14283260ecb403451a63945085390089552b20e Mon Sep 17 00:00:00 2001 From: gumengyu <1415515984yuri@gmail.com> Date: Fri, 15 Dec 2023 13:22:51 +0800 Subject: [PATCH] =?UTF-8?q?improve:=20=E8=AE=BE=E7=BD=AE=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E6=94=B9=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 下拉选择改为dialog, 参考 Android 系统内部设置关于选项的行为 - 一些列表对齐问题 - 字体设置预览文字居中 --- lib/pages/about/index.dart | 14 +- lib/pages/setting/extra_setting.dart | 62 ++++--- lib/pages/setting/pages/font_size_select.dart | 10 +- lib/pages/setting/play_setting.dart | 153 +++++++++--------- lib/pages/setting/style_setting.dart | 113 +++++-------- lib/pages/setting/widgets/select_dialog.dart | 68 ++++++++ lib/pages/setting/widgets/switch_item.dart | 1 + 7 files changed, 220 insertions(+), 201 deletions(-) create mode 100644 lib/pages/setting/widgets/select_dialog.dart diff --git a/lib/pages/about/index.dart b/lib/pages/about/index.dart index 31808e1c..d50946d6 100644 --- a/lib/pages/about/index.dart +++ b/lib/pages/about/index.dart @@ -34,11 +34,6 @@ class _AboutPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ - Divider( - thickness: 8, - height: 10, - color: Theme.of(context).colorScheme.onInverseSurface, - ), Image.asset( 'assets/images/logo/logo_android_2.png', width: 150, @@ -83,9 +78,9 @@ class _AboutPageState extends State { // ), // ), Divider( - thickness: 8, + thickness: 1, height: 30, - color: Theme.of(context).colorScheme.onInverseSurface, + color: Theme.of(context).colorScheme.outlineVariant, ), ListTile( onTap: () => _aboutController.githubUrl(), @@ -134,11 +129,6 @@ class _AboutPageState extends State { title: const Text('赞助'), trailing: Icon(Icons.arrow_forward_ios, size: 16, color: outline), ), - Divider( - thickness: 8, - height: 30, - color: Theme.of(context).colorScheme.onInverseSurface, - ), ], ), ), diff --git a/lib/pages/setting/extra_setting.dart b/lib/pages/setting/extra_setting.dart index 520a7c85..57c33ff4 100644 --- a/lib/pages/setting/extra_setting.dart +++ b/lib/pages/setting/extra_setting.dart @@ -3,6 +3,7 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:hive/hive.dart'; import 'package:pilipala/models/common/dynamics_type.dart'; import 'package:pilipala/models/common/reply_sort_type.dart'; +import 'package:pilipala/pages/setting/widgets/select_dialog.dart'; import 'package:pilipala/utils/storage.dart'; import 'widgets/switch_item.dart'; @@ -182,23 +183,21 @@ class _ExtraSettingState extends State { '当前优先展示「${ReplySortType.values[defaultReplySort].titles}」', style: subTitleStyle, ), - trailing: PopupMenuButton( - initialValue: defaultReplySort, - icon: const Icon(Icons.more_vert_outlined, size: 22), - onSelected: (item) { - defaultReplySort = item; - setting.put(SettingBoxKey.replySortType, item); + onTap: () async { + int? result = await showDialog( + context: context, + builder: (context) { + return SelectDialog(title: '评论展示', value: defaultReplySort, values: ReplySortType.values.map((e) { + return {'title': e.titles, 'value': e.index}; + }).toList()); + }, + ); + if (result != null) { + defaultReplySort = result; + setting.put(SettingBoxKey.replySortType, result); setState(() {}); - }, - itemBuilder: (BuildContext context) => [ - for (var i in ReplySortType.values) ...[ - PopupMenuItem( - value: i.index, - child: Text(i.titles), - ), - ] - ], - ), + } + }, ), ListTile( dense: false, @@ -207,23 +206,21 @@ class _ExtraSettingState extends State { '当前优先展示「${DynamicsType.values[defaultDynamicType].labels}」', style: subTitleStyle, ), - trailing: PopupMenuButton( - initialValue: defaultDynamicType, - icon: const Icon(Icons.more_vert_outlined, size: 22), - onSelected: (item) { - defaultDynamicType = item; - setting.put(SettingBoxKey.defaultDynamicType, item); + onTap: () async { + int? result = await showDialog( + context: context, + builder: (context) { + return SelectDialog(title: '动态展示', value: defaultDynamicType, values: DynamicsType.values.map((e) { + return {'title': e.labels, 'value': e.index}; + }).toList()); + }, + ); + if (result != null) { + defaultDynamicType = result; + setting.put(SettingBoxKey.defaultDynamicType, result); setState(() {}); - }, - itemBuilder: (BuildContext context) => [ - for (var i in DynamicsType.values) ...[ - PopupMenuItem( - value: i.index, - child: Text(i.labels), - ), - ] - ], - ), + } + }, ), ListTile( enableFeedback: true, @@ -231,6 +228,7 @@ class _ExtraSettingState extends State { title: Text('设置代理', style: titleStyle), subtitle: Text('设置代理 host:port', style: subTitleStyle), trailing: Transform.scale( + alignment: Alignment.centerRight, scale: 0.8, child: Switch( thumbIcon: MaterialStateProperty.resolveWith( diff --git a/lib/pages/setting/pages/font_size_select.dart b/lib/pages/setting/pages/font_size_select.dart index 04d6794d..4985c83f 100644 --- a/lib/pages/setting/pages/font_size_select.dart +++ b/lib/pages/setting/pages/font_size_select.dart @@ -44,12 +44,10 @@ class _FontSizeSelectPageState extends State { body: Column( children: [ Expanded( - child: SingleChildScrollView( - child: Center( - child: Text( - '当前字体大小:${currentSize == 1.0 ? '默认' : currentSize}', - style: TextStyle(fontSize: 14 * currentSize), - ), + child: Center( + child: Text( + '当前字体大小:${currentSize == 1.0 ? '默认' : currentSize}', + style: TextStyle(fontSize: 14 * currentSize), ), ), ), diff --git a/lib/pages/setting/play_setting.dart b/lib/pages/setting/play_setting.dart index 6dbfefcf..6bf5ada0 100644 --- a/lib/pages/setting/play_setting.dart +++ b/lib/pages/setting/play_setting.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:hive/hive.dart'; import 'package:pilipala/models/video/play/quality.dart'; +import 'package:pilipala/pages/setting/widgets/select_dialog.dart'; import 'package:pilipala/plugin/pl_player/index.dart'; import 'package:pilipala/services/service_locator.dart'; import 'package:pilipala/utils/storage.dart'; @@ -68,7 +69,7 @@ class _PlaySettingState extends State { dense: false, onTap: () => Get.toNamed('/playSpeedSet'), title: Text('倍速设置', style: titleStyle), - trailing: const Icon(Icons.arrow_forward_ios, size: 17), + subtitle: Text('设置视频播放速度', style: subTitleStyle), ), const SetSwitchItem( title: '开启1080P', @@ -149,23 +150,21 @@ class _PlaySettingState extends State { '当前画质${VideoQualityCode.fromCode(defaultVideoQa)!.description!}', style: subTitleStyle, ), - trailing: PopupMenuButton( - initialValue: defaultVideoQa, - icon: const Icon(Icons.more_vert_outlined, size: 22), - onSelected: (item) { - defaultVideoQa = item; - setting.put(SettingBoxKey.defaultVideoQa, item); + onTap: () async { + int? result = await showDialog( + context: context, + builder: (context) { + return SelectDialog(title: '默认画质', value: defaultVideoQa, values: VideoQuality.values.reversed.map((e) { + return {'title': e.description, 'value': e.code}; + }).toList()); + }, + ); + if (result != null) { + defaultVideoQa = result; + setting.put(SettingBoxKey.defaultVideoQa, result); setState(() {}); - }, - itemBuilder: (BuildContext context) => [ - for (var i in VideoQuality.values.reversed) ...[ - PopupMenuItem( - value: i.code, - child: Text(i.description), - ), - ] - ], - ), + } + }, ), ListTile( dense: false, @@ -174,23 +173,21 @@ class _PlaySettingState extends State { '当前音质${AudioQualityCode.fromCode(defaultAudioQa)!.description!}', style: subTitleStyle, ), - trailing: PopupMenuButton( - initialValue: defaultAudioQa, - icon: const Icon(Icons.more_vert_outlined, size: 22), - onSelected: (item) { - defaultAudioQa = item; - setting.put(SettingBoxKey.defaultAudioQa, item); + onTap: () async { + int? result = await showDialog( + context: context, + builder: (context) { + return SelectDialog(title: '默认音质', value: defaultAudioQa, values: AudioQuality.values.reversed.map((e) { + return {'title': e.description, 'value': e.code}; + }).toList()); + }, + ); + if (result != null) { + defaultAudioQa = result; + setting.put(SettingBoxKey.defaultAudioQa, result); setState(() {}); - }, - itemBuilder: (BuildContext context) => [ - for (var i in AudioQuality.values.reversed) ...[ - PopupMenuItem( - value: i.code, - child: Text(i.description), - ), - ] - ], - ), + } + }, ), ListTile( dense: false, @@ -199,23 +196,21 @@ class _PlaySettingState extends State { '当前解码格式${VideoDecodeFormatsCode.fromCode(defaultDecode)!.description!}', style: subTitleStyle, ), - trailing: PopupMenuButton( - initialValue: defaultDecode, - icon: const Icon(Icons.more_vert_outlined, size: 22), - onSelected: (item) { - defaultDecode = item; - setting.put(SettingBoxKey.defaultDecode, item); + onTap: () async { + String? result = await showDialog( + context: context, + builder: (context) { + return SelectDialog(title: '默认解码格式', value: defaultDecode, values: VideoDecodeFormats.values.map((e) { + return {'title': e.description, 'value': e.code}; + }).toList()); + }, + ); + if (result != null) { + defaultDecode = result; + setting.put(SettingBoxKey.defaultDecode, result); setState(() {}); - }, - itemBuilder: (BuildContext context) => [ - for (var i in VideoDecodeFormats.values) ...[ - PopupMenuItem( - value: i.code, - child: Text(i.description), - ), - ] - ], - ), + } + }, ), ListTile( dense: false, @@ -224,23 +219,21 @@ class _PlaySettingState extends State { '当前全屏方式:${FullScreenModeCode.fromCode(defaultFullScreenMode)!.description}', style: subTitleStyle, ), - trailing: PopupMenuButton( - initialValue: defaultFullScreenMode, - icon: const Icon(Icons.more_vert_outlined, size: 22), - onSelected: (item) { - defaultFullScreenMode = item; - setting.put(SettingBoxKey.fullScreenMode, item); + onTap: () async { + int? result = await showDialog( + context: context, + builder: (context) { + return SelectDialog(title: '默认全屏方式', value: defaultFullScreenMode, values: FullScreenMode.values.map((e) { + return {'title': e.description, 'value': e.code}; + }).toList()); + }, + ); + if (result != null) { + defaultFullScreenMode = result; + setting.put(SettingBoxKey.fullScreenMode, result); setState(() {}); - }, - itemBuilder: (BuildContext context) => [ - for (var i in FullScreenMode.values) ...[ - PopupMenuItem( - value: i.code, - child: Text(i.description), - ), - ] - ], - ), + } + }, ), ListTile( dense: false, @@ -249,23 +242,21 @@ class _PlaySettingState extends State { '当前展示方式:${BtmProgresBehaviorCode.fromCode(defaultBtmProgressBehavior)!.description}', style: subTitleStyle, ), - trailing: PopupMenuButton( - initialValue: defaultBtmProgressBehavior, - icon: const Icon(Icons.more_vert_outlined, size: 22), - onSelected: (item) { - defaultBtmProgressBehavior = item; - setting.put(SettingBoxKey.btmProgressBehavior, item); + onTap: () async { + int? result = await showDialog( + context: context, + builder: (context) { + return SelectDialog(title: '底部进度条展示', value: defaultBtmProgressBehavior, values: BtmProgresBehavior.values.map((e) { + return {'title': e.description, 'value': e.code}; + }).toList()); + }, + ); + if (result != null) { + defaultBtmProgressBehavior = result; + setting.put(SettingBoxKey.btmProgressBehavior, result); setState(() {}); - }, - itemBuilder: (BuildContext context) => [ - for (var i in BtmProgresBehavior.values) ...[ - PopupMenuItem( - value: i.code, - child: Text(i.description), - ), - ] - ], - ), + } + }, ), ], ), diff --git a/lib/pages/setting/style_setting.dart b/lib/pages/setting/style_setting.dart index 43335318..277919dd 100644 --- a/lib/pages/setting/style_setting.dart +++ b/lib/pages/setting/style_setting.dart @@ -4,6 +4,8 @@ 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/pages/setting/pages/color_select.dart'; +import 'package:pilipala/pages/setting/widgets/select_dialog.dart'; import 'package:pilipala/utils/storage.dart'; import 'controller.dart'; @@ -18,6 +20,8 @@ class StyleSetting extends StatefulWidget { class _StyleSettingState extends State { final SettingController settingController = Get.put(SettingController()); + final ColorSelectController colorSelectController = Get.put(ColorSelectController()); + Box setting = GStrorage.setting; late int picQuality; late ThemeType _tempThemeValue; @@ -56,6 +60,7 @@ class _StyleSettingState extends State { title: const Text('震动反馈'), subtitle: Text('请确定手机设置中已开启震动反馈', style: subTitleStyle), trailing: Transform.scale( + alignment: Alignment.centerRight, scale: 0.8, child: Switch( thumbIcon: MaterialStateProperty.resolveWith( @@ -98,29 +103,27 @@ class _StyleSettingState extends State { needReboot: true, ), ListTile( + onTap: () async { + int? result = await showDialog( + context: context, + builder: (context) { + return SelectDialog(title: '自定义列数', value: defaultCustomRows, values: [1, 2, 3, 4, 5].map((e) { + return {'title': '$e 列', 'value': e}; + }).toList()); + }, + ); + if (result != null) { + defaultCustomRows = result; + setting.put(SettingBoxKey.customRows, result); + setState(() {}); + } + }, dense: false, title: Text('自定义列数', style: titleStyle), subtitle: Text( - '当前列数', + '当前列数 $defaultCustomRows 列', style: subTitleStyle, ), - trailing: PopupMenuButton( - initialValue: defaultCustomRows, - icon: const Icon(Icons.more_vert_outlined, size: 22), - onSelected: (item) { - defaultCustomRows = item; - setting.put(SettingBoxKey.customRows, item); - setState(() {}); - }, - itemBuilder: (BuildContext context) => [ - for (var i in [1, 2, 3, 4, 5]) ...[ - PopupMenuItem( - value: i, - child: Text(i.toString()), - ), - ] - ], - ), ), ListTile( dense: false, @@ -176,88 +179,58 @@ class _StyleSettingState extends State { }, title: Text('图片质量', style: titleStyle), subtitle: Text('选择合适的图片清晰度,上限100%', style: subTitleStyle), - trailing: Obx( - () => Text( - '${settingController.picQuality.value}%', - style: Theme.of(context).textTheme.titleSmall, + trailing: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Obx( + () => Text( + '${settingController.picQuality.value}%', + style: Theme.of(context).textTheme.titleSmall, + ), ), ), ), ListTile( dense: false, - onTap: () { - showDialog( + onTap: () async { + ThemeType? result = await 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('确定')) - ], - ); + return SelectDialog(title: '主题模式', value: _tempThemeValue, values: ThemeType.values.map((e) { + return {'title': e.description, 'value': e}; + }).toList()); }, ); + if (result != null) { + _tempThemeValue = result; + settingController.themeType.value = result; + setting.put( + SettingBoxKey.themeMode, result.code); + Get.forceAppUpdate(); + } }, title: Text('主题模式', style: titleStyle), subtitle: Obx(() => Text( '当前模式:${settingController.themeType.value.description}', style: subTitleStyle)), - trailing: const Icon(Icons.arrow_right_alt_outlined), ), ListTile( dense: false, onTap: () => Get.toNamed('/colorSetting'), title: Text('应用主题', style: titleStyle), - trailing: const Icon(Icons.arrow_forward_ios, size: 17), + subtitle: Obx(() => Text( + '当前主题:${colorSelectController.type.value == 0 ? '动态取色': '指定颜色'}', + style: subTitleStyle)), ), ListTile( dense: false, onTap: () => Get.toNamed('/fontSizeSetting'), title: Text('字体大小', style: titleStyle), - trailing: const Icon(Icons.arrow_forward_ios, size: 17), ), if (Platform.isAndroid) ListTile( dense: false, onTap: () => Get.toNamed('/displayModeSetting'), title: Text('屏幕帧率', style: titleStyle), - trailing: const Icon(Icons.arrow_forward_ios, size: 17), ) ], ), diff --git a/lib/pages/setting/widgets/select_dialog.dart b/lib/pages/setting/widgets/select_dialog.dart new file mode 100644 index 00000000..dffa4571 --- /dev/null +++ b/lib/pages/setting/widgets/select_dialog.dart @@ -0,0 +1,68 @@ +import 'package:flutter/material.dart'; +import 'package:pilipala/models/common/theme_type.dart'; + +class SelectDialog extends StatefulWidget { + final T value; + final String title; + final List values; + const SelectDialog({super.key, required this.value, required this.values, required this.title}); + + @override + _SelectDialogState createState() => _SelectDialogState(); +} + +class _SelectDialogState extends State> { + + late T _tempValue; + + @override + void initState() { + super.initState(); + _tempValue = widget.value; + } + + @override + Widget build(BuildContext context) { + TextStyle titleStyle = Theme.of(context).textTheme.titleMedium!; + + return AlertDialog( + title: Text(widget.title), + contentPadding: const EdgeInsets.fromLTRB(0, 12, 0, 12), + content: StatefulBuilder( + builder: (context, StateSetter setState) { + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + for (var i in widget.values) ...[ + RadioListTile( + value: i['value'], + title: Text(i['title'], style: titleStyle), + groupValue: _tempValue, + onChanged: (value) { + print(value); + setState(() { + _tempValue = value as T; + }); + }, + ), + ] + ], + ), + ); + }), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text( + '取消', + style: TextStyle( + color: Theme.of(context).colorScheme.outline), + )), + TextButton( + onPressed: () => Navigator.pop(context, _tempValue), + child: const Text('确定')) + ], + ); + } +} diff --git a/lib/pages/setting/widgets/switch_item.dart b/lib/pages/setting/widgets/switch_item.dart index 488ade14..d0c2bbf2 100644 --- a/lib/pages/setting/widgets/switch_item.dart +++ b/lib/pages/setting/widgets/switch_item.dart @@ -67,6 +67,7 @@ class _SetSwitchItemState extends State { ? Text(widget.subTitle!, style: subTitleStyle) : null, trailing: Transform.scale( + alignment: Alignment.centerRight, // 缩放Switch的大小后保持右侧对齐, 避免右侧空隙过大 scale: 0.8, child: Switch( thumbIcon: MaterialStateProperty.resolveWith(