| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- import 'dart:math';
- import 'package:flutter/material.dart';
- import 'package:puzzleweave/audio/jc_audio_controller.dart';
- import 'package:puzzleweave/l10n/app_localizations.dart';
- import 'package:puzzleweave/models/items.dart';
- import 'package:puzzleweave/play/board_play.dart';
- import 'package:puzzleweave/settings/settings_controller.dart';
- import 'package:puzzleweave/skin/skin.dart';
- import 'package:puzzleweave/utils/mybutton.dart';
- import 'package:provider/provider.dart';
- class SettingsDialog extends StatefulWidget {
- final ListItem? item;
- final bool showReturn;
- final bool showRestart;
- const SettingsDialog({super.key, required this.showReturn, required this.showRestart, required this.item});
- @override
- State<StatefulWidget> createState() => _SettingDialogState();
- static PageRouteBuilder buildRoute({bool showReturn = false, bool showRestart = false, ListItem? item}) {
- return PageRouteBuilder(
- opaque: false, // 不遮盖原来的图层
- pageBuilder: (context, animation, secondaryAnimation) {
- return SettingsDialog(showReturn: showReturn, showRestart: showRestart, item: item);
- },
- transitionsBuilder: (context, animation, secondaryAnimation, child) {
- return FadeTransition(opacity: animation, child: child);
- },
- );
- }
- }
- class _SettingDialogState extends State<SettingsDialog> {
- @override
- Widget build(BuildContext context) {
- final settings = context.watch<SettingsController>();
- final audio = context.read<JcAudioController>();
- Widget gap = const SizedBox(height: 10);
- // 背景色(开启/关闭状态)
- const activeBgColor = Colors.white;
- const inactiveBgColor = Color.fromARGB(255, 205, 195, 195);
- // 图标颜色(固定,与背景形成对比)
- final iconColor = SkinHelper.slotBorderColor;
- return Scaffold(
- // backgroundColor: SkinHelper.coreBgColor,
- backgroundColor: Colors.black.withAlpha(128),
- body: Center(
- child: LayoutBuilder(
- builder: (context, constraints) {
- const double maxContainerWidth = 500; // 设定一个对话框最大宽度,避免在pad上显示过宽过大不好看
- final containerWidth = min(constraints.biggest.shortestSide * 0.75, maxContainerWidth);
- final buttonWidth = containerWidth * 0.8;
- return Container(
- width: containerWidth,
- decoration: BoxDecoration(color: SkinHelper.coreBgColor, borderRadius: const BorderRadius.all(Radius.circular(16))),
- child: Column(
- mainAxisSize: MainAxisSize.min,
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- // 标题栏(关闭按钮 + 标题)
- Row(
- mainAxisSize: MainAxisSize.max,
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- IconButton(
- icon: const Icon(Icons.close_rounded, color: Colors.white),
- onPressed: () {
- audio.playSfx(SfxType.click);
- Navigator.pop(context);
- },
- ),
- Text(
- AppLocalizations.of(context)!.setting,
- style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold),
- ),
- const SizedBox(width: 48), // 占位,与左侧关闭按钮平衡
- ],
- ),
- gap,
- gap,
- // 重新开始按钮
- if (widget.showRestart)
- MyElevatedButton(
- onPressed: () {
- audio.playSfx(SfxType.click);
- PageRouteBuilder? pageRouteBuilder = BoardPlay.buildRoute(widget.item!);
- Navigator.pop(context);
- Navigator.pushReplacement(context, pageRouteBuilder);
- },
- width: buttonWidth,
- borderRadius: BorderRadius.circular(20),
- gradient: const LinearGradient(colors: [Colors.white, Colors.white]),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Icon(Icons.restart_alt_rounded, size: 24, weight: 600, color: SkinHelper.slotBorderColor),
- const SizedBox(width: 5),
- Text(AppLocalizations.of(context)!.restart, style: TextStyle(color: SkinHelper.slotBorderColor, fontSize: 18)),
- ],
- ),
- ),
- if (widget.showReturn) gap,
- if (widget.showReturn) gap,
- // 回到主页按钮
- if (widget.showReturn)
- MyElevatedButton(
- onPressed: () {
- audio.playSfx(SfxType.click);
- Navigator.pop(context);
- Navigator.pop(context);
- },
- width: buttonWidth,
- borderRadius: BorderRadius.circular(20),
- gradient: const LinearGradient(colors: [Colors.white, Colors.white]),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Icon(Icons.arrow_back, size: 24, weight: 600, color: SkinHelper.slotBorderColor),
- const SizedBox(width: 5),
- Text(AppLocalizations.of(context)!.backToHome, style: TextStyle(color: SkinHelper.slotBorderColor, fontSize: 18)),
- ],
- ),
- ),
- gap,
- gap,
- gap,
- // 三个设置项(用ValueListenableBuilder监听状态变化)
- Padding(
- padding: const EdgeInsets.symmetric(horizontal: 20),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- // 1. 背景音乐设置(监听music状态)
- ValueListenableBuilder<bool>(
- valueListenable: settings.music, // 监听music的变化
- builder: (context, isMusicOn, child) {
- // 状态变化时,自动重建此按钮
- return _buildSettingButton(
- icon: isMusicOn ? Icons.music_note : Icons.music_off,
- bgColor: isMusicOn ? activeBgColor : inactiveBgColor,
- iconColor: iconColor,
- onPressed: () {
- audio.playSfx(SfxType.click);
- settings.toggleMusic();
- },
- );
- },
- ),
- // 2. 音效设置(监听sound状态)
- ValueListenableBuilder<bool>(
- valueListenable: settings.sound, // 监听sound的变化
- builder: (context, isSoundOn, child) {
- return _buildSettingButton(
- icon: isSoundOn ? Icons.volume_up : Icons.volume_off,
- bgColor: isSoundOn ? activeBgColor : inactiveBgColor,
- iconColor: iconColor,
- onPressed: () {
- audio.playSfx(SfxType.click);
- settings.toggleSound();
- },
- );
- },
- ),
- // 3. 震动设置(监听vibrate状态)
- ValueListenableBuilder<bool>(
- valueListenable: settings.vibrate, // 监听vibrate的变化
- builder: (context, isVibrateOn, child) {
- return _buildSettingButton(
- icon: isVibrateOn ? Icons.vibration : Icons.crop_portrait,
- bgColor: isVibrateOn ? activeBgColor : inactiveBgColor,
- iconColor: iconColor,
- onPressed: () {
- audio.playSfx(SfxType.click);
- settings.toggleVibrate();
- },
- );
- },
- ),
- ],
- ),
- ),
- gap,
- gap,
- gap,
- ],
- ),
- );
- },
- ),
- ),
- );
- }
- // 封装设置项按钮(无需额外key,由ValueListenableBuilder保证重绘)
- Widget _buildSettingButton({required IconData icon, required Color bgColor, required Color iconColor, required VoidCallback onPressed}) {
- return InkWell(
- // 圆形点击区域
- borderRadius: BorderRadius.circular(30),
- onTap: onPressed,
- child: Container(
- width: 56,
- height: 56,
- decoration: BoxDecoration(color: bgColor, shape: BoxShape.circle),
- child: Icon(icon, size: 28, color: iconColor),
- ),
- );
- }
- }
|