improve: 设置页面样式改进
- 下拉选择改为dialog, 参考 Android 系统内部设置关于选项的行为 - 一些列表对齐问题 - 字体设置预览文字居中
This commit is contained in:
@ -34,11 +34,6 @@ class _AboutPageState extends State<AboutPage> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Divider(
|
|
||||||
thickness: 8,
|
|
||||||
height: 10,
|
|
||||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
|
||||||
),
|
|
||||||
Image.asset(
|
Image.asset(
|
||||||
'assets/images/logo/logo_android_2.png',
|
'assets/images/logo/logo_android_2.png',
|
||||||
width: 150,
|
width: 150,
|
||||||
@ -83,9 +78,9 @@ class _AboutPageState extends State<AboutPage> {
|
|||||||
// ),
|
// ),
|
||||||
// ),
|
// ),
|
||||||
Divider(
|
Divider(
|
||||||
thickness: 8,
|
thickness: 1,
|
||||||
height: 30,
|
height: 30,
|
||||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
color: Theme.of(context).colorScheme.outlineVariant,
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
onTap: () => _aboutController.githubUrl(),
|
onTap: () => _aboutController.githubUrl(),
|
||||||
@ -134,11 +129,6 @@ class _AboutPageState extends State<AboutPage> {
|
|||||||
title: const Text('赞助'),
|
title: const Text('赞助'),
|
||||||
trailing: Icon(Icons.arrow_forward_ios, size: 16, color: outline),
|
trailing: Icon(Icons.arrow_forward_ios, size: 16, color: outline),
|
||||||
),
|
),
|
||||||
Divider(
|
|
||||||
thickness: 8,
|
|
||||||
height: 30,
|
|
||||||
color: Theme.of(context).colorScheme.onInverseSurface,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -3,6 +3,7 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:pilipala/models/common/dynamics_type.dart';
|
import 'package:pilipala/models/common/dynamics_type.dart';
|
||||||
import 'package:pilipala/models/common/reply_sort_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 'package:pilipala/utils/storage.dart';
|
||||||
|
|
||||||
import 'widgets/switch_item.dart';
|
import 'widgets/switch_item.dart';
|
||||||
@ -182,23 +183,21 @@ class _ExtraSettingState extends State<ExtraSetting> {
|
|||||||
'当前优先展示「${ReplySortType.values[defaultReplySort].titles}」',
|
'当前优先展示「${ReplySortType.values[defaultReplySort].titles}」',
|
||||||
style: subTitleStyle,
|
style: subTitleStyle,
|
||||||
),
|
),
|
||||||
trailing: PopupMenuButton(
|
onTap: () async {
|
||||||
initialValue: defaultReplySort,
|
int? result = await showDialog(
|
||||||
icon: const Icon(Icons.more_vert_outlined, size: 22),
|
context: context,
|
||||||
onSelected: (item) {
|
builder: (context) {
|
||||||
defaultReplySort = item;
|
return SelectDialog<int>(title: '评论展示', value: defaultReplySort, values: ReplySortType.values.map((e) {
|
||||||
setting.put(SettingBoxKey.replySortType, item);
|
return {'title': e.titles, 'value': e.index};
|
||||||
|
}).toList());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (result != null) {
|
||||||
|
defaultReplySort = result;
|
||||||
|
setting.put(SettingBoxKey.replySortType, result);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
}
|
||||||
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
|
},
|
||||||
for (var i in ReplySortType.values) ...[
|
|
||||||
PopupMenuItem(
|
|
||||||
value: i.index,
|
|
||||||
child: Text(i.titles),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
dense: false,
|
dense: false,
|
||||||
@ -207,23 +206,21 @@ class _ExtraSettingState extends State<ExtraSetting> {
|
|||||||
'当前优先展示「${DynamicsType.values[defaultDynamicType].labels}」',
|
'当前优先展示「${DynamicsType.values[defaultDynamicType].labels}」',
|
||||||
style: subTitleStyle,
|
style: subTitleStyle,
|
||||||
),
|
),
|
||||||
trailing: PopupMenuButton(
|
onTap: () async {
|
||||||
initialValue: defaultDynamicType,
|
int? result = await showDialog(
|
||||||
icon: const Icon(Icons.more_vert_outlined, size: 22),
|
context: context,
|
||||||
onSelected: (item) {
|
builder: (context) {
|
||||||
defaultDynamicType = item;
|
return SelectDialog<int>(title: '动态展示', value: defaultDynamicType, values: DynamicsType.values.map((e) {
|
||||||
setting.put(SettingBoxKey.defaultDynamicType, item);
|
return {'title': e.labels, 'value': e.index};
|
||||||
|
}).toList());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (result != null) {
|
||||||
|
defaultDynamicType = result;
|
||||||
|
setting.put(SettingBoxKey.defaultDynamicType, result);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
}
|
||||||
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
|
},
|
||||||
for (var i in DynamicsType.values) ...[
|
|
||||||
PopupMenuItem(
|
|
||||||
value: i.index,
|
|
||||||
child: Text(i.labels),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
enableFeedback: true,
|
enableFeedback: true,
|
||||||
@ -231,6 +228,7 @@ class _ExtraSettingState extends State<ExtraSetting> {
|
|||||||
title: Text('设置代理', style: titleStyle),
|
title: Text('设置代理', style: titleStyle),
|
||||||
subtitle: Text('设置代理 host:port', style: subTitleStyle),
|
subtitle: Text('设置代理 host:port', style: subTitleStyle),
|
||||||
trailing: Transform.scale(
|
trailing: Transform.scale(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
scale: 0.8,
|
scale: 0.8,
|
||||||
child: Switch(
|
child: Switch(
|
||||||
thumbIcon: MaterialStateProperty.resolveWith<Icon?>(
|
thumbIcon: MaterialStateProperty.resolveWith<Icon?>(
|
||||||
|
@ -44,12 +44,10 @@ class _FontSizeSelectPageState extends State<FontSizeSelectPage> {
|
|||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: SingleChildScrollView(
|
child: Center(
|
||||||
child: Center(
|
child: Text(
|
||||||
child: Text(
|
'当前字体大小:${currentSize == 1.0 ? '默认' : currentSize}',
|
||||||
'当前字体大小:${currentSize == 1.0 ? '默认' : currentSize}',
|
style: TextStyle(fontSize: 14 * currentSize),
|
||||||
style: TextStyle(fontSize: 14 * currentSize),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:pilipala/models/video/play/quality.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/plugin/pl_player/index.dart';
|
||||||
import 'package:pilipala/services/service_locator.dart';
|
import 'package:pilipala/services/service_locator.dart';
|
||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
@ -68,7 +69,7 @@ class _PlaySettingState extends State<PlaySetting> {
|
|||||||
dense: false,
|
dense: false,
|
||||||
onTap: () => Get.toNamed('/playSpeedSet'),
|
onTap: () => Get.toNamed('/playSpeedSet'),
|
||||||
title: Text('倍速设置', style: titleStyle),
|
title: Text('倍速设置', style: titleStyle),
|
||||||
trailing: const Icon(Icons.arrow_forward_ios, size: 17),
|
subtitle: Text('设置视频播放速度', style: subTitleStyle),
|
||||||
),
|
),
|
||||||
const SetSwitchItem(
|
const SetSwitchItem(
|
||||||
title: '开启1080P',
|
title: '开启1080P',
|
||||||
@ -149,23 +150,21 @@ class _PlaySettingState extends State<PlaySetting> {
|
|||||||
'当前画质${VideoQualityCode.fromCode(defaultVideoQa)!.description!}',
|
'当前画质${VideoQualityCode.fromCode(defaultVideoQa)!.description!}',
|
||||||
style: subTitleStyle,
|
style: subTitleStyle,
|
||||||
),
|
),
|
||||||
trailing: PopupMenuButton(
|
onTap: () async {
|
||||||
initialValue: defaultVideoQa,
|
int? result = await showDialog(
|
||||||
icon: const Icon(Icons.more_vert_outlined, size: 22),
|
context: context,
|
||||||
onSelected: (item) {
|
builder: (context) {
|
||||||
defaultVideoQa = item;
|
return SelectDialog<int>(title: '默认画质', value: defaultVideoQa, values: VideoQuality.values.reversed.map((e) {
|
||||||
setting.put(SettingBoxKey.defaultVideoQa, item);
|
return {'title': e.description, 'value': e.code};
|
||||||
|
}).toList());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (result != null) {
|
||||||
|
defaultVideoQa = result;
|
||||||
|
setting.put(SettingBoxKey.defaultVideoQa, result);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
}
|
||||||
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
|
},
|
||||||
for (var i in VideoQuality.values.reversed) ...[
|
|
||||||
PopupMenuItem(
|
|
||||||
value: i.code,
|
|
||||||
child: Text(i.description),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
dense: false,
|
dense: false,
|
||||||
@ -174,23 +173,21 @@ class _PlaySettingState extends State<PlaySetting> {
|
|||||||
'当前音质${AudioQualityCode.fromCode(defaultAudioQa)!.description!}',
|
'当前音质${AudioQualityCode.fromCode(defaultAudioQa)!.description!}',
|
||||||
style: subTitleStyle,
|
style: subTitleStyle,
|
||||||
),
|
),
|
||||||
trailing: PopupMenuButton(
|
onTap: () async {
|
||||||
initialValue: defaultAudioQa,
|
int? result = await showDialog(
|
||||||
icon: const Icon(Icons.more_vert_outlined, size: 22),
|
context: context,
|
||||||
onSelected: (item) {
|
builder: (context) {
|
||||||
defaultAudioQa = item;
|
return SelectDialog<int>(title: '默认音质', value: defaultAudioQa, values: AudioQuality.values.reversed.map((e) {
|
||||||
setting.put(SettingBoxKey.defaultAudioQa, item);
|
return {'title': e.description, 'value': e.code};
|
||||||
|
}).toList());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (result != null) {
|
||||||
|
defaultAudioQa = result;
|
||||||
|
setting.put(SettingBoxKey.defaultAudioQa, result);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
}
|
||||||
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
|
},
|
||||||
for (var i in AudioQuality.values.reversed) ...[
|
|
||||||
PopupMenuItem(
|
|
||||||
value: i.code,
|
|
||||||
child: Text(i.description),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
dense: false,
|
dense: false,
|
||||||
@ -199,23 +196,21 @@ class _PlaySettingState extends State<PlaySetting> {
|
|||||||
'当前解码格式${VideoDecodeFormatsCode.fromCode(defaultDecode)!.description!}',
|
'当前解码格式${VideoDecodeFormatsCode.fromCode(defaultDecode)!.description!}',
|
||||||
style: subTitleStyle,
|
style: subTitleStyle,
|
||||||
),
|
),
|
||||||
trailing: PopupMenuButton(
|
onTap: () async {
|
||||||
initialValue: defaultDecode,
|
String? result = await showDialog(
|
||||||
icon: const Icon(Icons.more_vert_outlined, size: 22),
|
context: context,
|
||||||
onSelected: (item) {
|
builder: (context) {
|
||||||
defaultDecode = item;
|
return SelectDialog<String>(title: '默认解码格式', value: defaultDecode, values: VideoDecodeFormats.values.map((e) {
|
||||||
setting.put(SettingBoxKey.defaultDecode, item);
|
return {'title': e.description, 'value': e.code};
|
||||||
|
}).toList());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (result != null) {
|
||||||
|
defaultDecode = result;
|
||||||
|
setting.put(SettingBoxKey.defaultDecode, result);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
}
|
||||||
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
|
},
|
||||||
for (var i in VideoDecodeFormats.values) ...[
|
|
||||||
PopupMenuItem(
|
|
||||||
value: i.code,
|
|
||||||
child: Text(i.description),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
dense: false,
|
dense: false,
|
||||||
@ -224,23 +219,21 @@ class _PlaySettingState extends State<PlaySetting> {
|
|||||||
'当前全屏方式:${FullScreenModeCode.fromCode(defaultFullScreenMode)!.description}',
|
'当前全屏方式:${FullScreenModeCode.fromCode(defaultFullScreenMode)!.description}',
|
||||||
style: subTitleStyle,
|
style: subTitleStyle,
|
||||||
),
|
),
|
||||||
trailing: PopupMenuButton(
|
onTap: () async {
|
||||||
initialValue: defaultFullScreenMode,
|
int? result = await showDialog(
|
||||||
icon: const Icon(Icons.more_vert_outlined, size: 22),
|
context: context,
|
||||||
onSelected: (item) {
|
builder: (context) {
|
||||||
defaultFullScreenMode = item;
|
return SelectDialog<int>(title: '默认全屏方式', value: defaultFullScreenMode, values: FullScreenMode.values.map((e) {
|
||||||
setting.put(SettingBoxKey.fullScreenMode, item);
|
return {'title': e.description, 'value': e.code};
|
||||||
|
}).toList());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (result != null) {
|
||||||
|
defaultFullScreenMode = result;
|
||||||
|
setting.put(SettingBoxKey.fullScreenMode, result);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
}
|
||||||
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
|
},
|
||||||
for (var i in FullScreenMode.values) ...[
|
|
||||||
PopupMenuItem(
|
|
||||||
value: i.code,
|
|
||||||
child: Text(i.description),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
dense: false,
|
dense: false,
|
||||||
@ -249,23 +242,21 @@ class _PlaySettingState extends State<PlaySetting> {
|
|||||||
'当前展示方式:${BtmProgresBehaviorCode.fromCode(defaultBtmProgressBehavior)!.description}',
|
'当前展示方式:${BtmProgresBehaviorCode.fromCode(defaultBtmProgressBehavior)!.description}',
|
||||||
style: subTitleStyle,
|
style: subTitleStyle,
|
||||||
),
|
),
|
||||||
trailing: PopupMenuButton(
|
onTap: () async {
|
||||||
initialValue: defaultBtmProgressBehavior,
|
int? result = await showDialog(
|
||||||
icon: const Icon(Icons.more_vert_outlined, size: 22),
|
context: context,
|
||||||
onSelected: (item) {
|
builder: (context) {
|
||||||
defaultBtmProgressBehavior = item;
|
return SelectDialog<int>(title: '底部进度条展示', value: defaultBtmProgressBehavior, values: BtmProgresBehavior.values.map((e) {
|
||||||
setting.put(SettingBoxKey.btmProgressBehavior, item);
|
return {'title': e.description, 'value': e.code};
|
||||||
|
}).toList());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (result != null) {
|
||||||
|
defaultBtmProgressBehavior = result;
|
||||||
|
setting.put(SettingBoxKey.btmProgressBehavior, result);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
}
|
||||||
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
|
},
|
||||||
for (var i in BtmProgresBehavior.values) ...[
|
|
||||||
PopupMenuItem(
|
|
||||||
value: i.code,
|
|
||||||
child: Text(i.description),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -4,6 +4,8 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:pilipala/models/common/theme_type.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 'package:pilipala/utils/storage.dart';
|
||||||
|
|
||||||
import 'controller.dart';
|
import 'controller.dart';
|
||||||
@ -18,6 +20,8 @@ class StyleSetting extends StatefulWidget {
|
|||||||
|
|
||||||
class _StyleSettingState extends State<StyleSetting> {
|
class _StyleSettingState extends State<StyleSetting> {
|
||||||
final SettingController settingController = Get.put(SettingController());
|
final SettingController settingController = Get.put(SettingController());
|
||||||
|
final ColorSelectController colorSelectController = Get.put(ColorSelectController());
|
||||||
|
|
||||||
Box setting = GStrorage.setting;
|
Box setting = GStrorage.setting;
|
||||||
late int picQuality;
|
late int picQuality;
|
||||||
late ThemeType _tempThemeValue;
|
late ThemeType _tempThemeValue;
|
||||||
@ -56,6 +60,7 @@ class _StyleSettingState extends State<StyleSetting> {
|
|||||||
title: const Text('震动反馈'),
|
title: const Text('震动反馈'),
|
||||||
subtitle: Text('请确定手机设置中已开启震动反馈', style: subTitleStyle),
|
subtitle: Text('请确定手机设置中已开启震动反馈', style: subTitleStyle),
|
||||||
trailing: Transform.scale(
|
trailing: Transform.scale(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
scale: 0.8,
|
scale: 0.8,
|
||||||
child: Switch(
|
child: Switch(
|
||||||
thumbIcon: MaterialStateProperty.resolveWith<Icon?>(
|
thumbIcon: MaterialStateProperty.resolveWith<Icon?>(
|
||||||
@ -98,29 +103,27 @@ class _StyleSettingState extends State<StyleSetting> {
|
|||||||
needReboot: true,
|
needReboot: true,
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
|
onTap: () async {
|
||||||
|
int? result = await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return SelectDialog<int>(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,
|
dense: false,
|
||||||
title: Text('自定义列数', style: titleStyle),
|
title: Text('自定义列数', style: titleStyle),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
'当前列数',
|
'当前列数 $defaultCustomRows 列',
|
||||||
style: subTitleStyle,
|
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) => <PopupMenuEntry>[
|
|
||||||
for (var i in [1, 2, 3, 4, 5]) ...[
|
|
||||||
PopupMenuItem(
|
|
||||||
value: i,
|
|
||||||
child: Text(i.toString()),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
dense: false,
|
dense: false,
|
||||||
@ -176,88 +179,58 @@ class _StyleSettingState extends State<StyleSetting> {
|
|||||||
},
|
},
|
||||||
title: Text('图片质量', style: titleStyle),
|
title: Text('图片质量', style: titleStyle),
|
||||||
subtitle: Text('选择合适的图片清晰度,上限100%', style: subTitleStyle),
|
subtitle: Text('选择合适的图片清晰度,上限100%', style: subTitleStyle),
|
||||||
trailing: Obx(
|
trailing: Padding(
|
||||||
() => Text(
|
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
'${settingController.picQuality.value}%',
|
child: Obx(
|
||||||
style: Theme.of(context).textTheme.titleSmall,
|
() => Text(
|
||||||
|
'${settingController.picQuality.value}%',
|
||||||
|
style: Theme.of(context).textTheme.titleSmall,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
dense: false,
|
dense: false,
|
||||||
onTap: () {
|
onTap: () async {
|
||||||
showDialog(
|
ThemeType? result = await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return AlertDialog(
|
return SelectDialog<ThemeType>(title: '主题模式', value: _tempThemeValue, values: ThemeType.values.map((e) {
|
||||||
title: const Text('主题模式'),
|
return {'title': e.description, 'value': e};
|
||||||
contentPadding: const EdgeInsets.fromLTRB(0, 12, 0, 12),
|
}).toList());
|
||||||
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('确定'))
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
if (result != null) {
|
||||||
|
_tempThemeValue = result;
|
||||||
|
settingController.themeType.value = result;
|
||||||
|
setting.put(
|
||||||
|
SettingBoxKey.themeMode, result.code);
|
||||||
|
Get.forceAppUpdate();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
title: Text('主题模式', style: titleStyle),
|
title: Text('主题模式', style: titleStyle),
|
||||||
subtitle: Obx(() => Text(
|
subtitle: Obx(() => Text(
|
||||||
'当前模式:${settingController.themeType.value.description}',
|
'当前模式:${settingController.themeType.value.description}',
|
||||||
style: subTitleStyle)),
|
style: subTitleStyle)),
|
||||||
trailing: const Icon(Icons.arrow_right_alt_outlined),
|
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
dense: false,
|
dense: false,
|
||||||
onTap: () => Get.toNamed('/colorSetting'),
|
onTap: () => Get.toNamed('/colorSetting'),
|
||||||
title: Text('应用主题', style: titleStyle),
|
title: Text('应用主题', style: titleStyle),
|
||||||
trailing: const Icon(Icons.arrow_forward_ios, size: 17),
|
subtitle: Obx(() => Text(
|
||||||
|
'当前主题:${colorSelectController.type.value == 0 ? '动态取色': '指定颜色'}',
|
||||||
|
style: subTitleStyle)),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
dense: false,
|
dense: false,
|
||||||
onTap: () => Get.toNamed('/fontSizeSetting'),
|
onTap: () => Get.toNamed('/fontSizeSetting'),
|
||||||
title: Text('字体大小', style: titleStyle),
|
title: Text('字体大小', style: titleStyle),
|
||||||
trailing: const Icon(Icons.arrow_forward_ios, size: 17),
|
|
||||||
),
|
),
|
||||||
if (Platform.isAndroid)
|
if (Platform.isAndroid)
|
||||||
ListTile(
|
ListTile(
|
||||||
dense: false,
|
dense: false,
|
||||||
onTap: () => Get.toNamed('/displayModeSetting'),
|
onTap: () => Get.toNamed('/displayModeSetting'),
|
||||||
title: Text('屏幕帧率', style: titleStyle),
|
title: Text('屏幕帧率', style: titleStyle),
|
||||||
trailing: const Icon(Icons.arrow_forward_ios, size: 17),
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
68
lib/pages/setting/widgets/select_dialog.dart
Normal file
68
lib/pages/setting/widgets/select_dialog.dart
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:pilipala/models/common/theme_type.dart';
|
||||||
|
|
||||||
|
class SelectDialog<T> extends StatefulWidget {
|
||||||
|
final T value;
|
||||||
|
final String title;
|
||||||
|
final List<dynamic> values;
|
||||||
|
const SelectDialog({super.key, required this.value, required this.values, required this.title});
|
||||||
|
|
||||||
|
@override
|
||||||
|
_SelectDialogState<T> createState() => _SelectDialogState<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SelectDialogState<T> extends State<SelectDialog<T>> {
|
||||||
|
|
||||||
|
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('确定'))
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -67,6 +67,7 @@ class _SetSwitchItemState extends State<SetSwitchItem> {
|
|||||||
? Text(widget.subTitle!, style: subTitleStyle)
|
? Text(widget.subTitle!, style: subTitleStyle)
|
||||||
: null,
|
: null,
|
||||||
trailing: Transform.scale(
|
trailing: Transform.scale(
|
||||||
|
alignment: Alignment.centerRight, // 缩放Switch的大小后保持右侧对齐, 避免右侧空隙过大
|
||||||
scale: 0.8,
|
scale: 0.8,
|
||||||
child: Switch(
|
child: Switch(
|
||||||
thumbIcon: MaterialStateProperty.resolveWith<Icon?>(
|
thumbIcon: MaterialStateProperty.resolveWith<Icon?>(
|
||||||
|
Reference in New Issue
Block a user