/// 时间: 2026-04-02 /// 功能: 主页设置和控制组件 /// 介绍: 包含收起/恢复悬浮按钮的管理器和组件 /// 最新变化: 2026-04-02 初始创建 import 'dart:async'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../../../constants/app_constants.dart'; /// 悬浮按钮收起管理器 class FloatingButtonsVisibilityManager { static const String _key = 'floating_buttons_visible'; static FloatingButtonsVisibilityManager? _instance; bool _isVisible = true; bool _isFlashing = false; int _flashCount = 0; final ValueNotifier _visibleNotifier = ValueNotifier(true); final ValueNotifier _flashingNotifier = ValueNotifier(false); Timer? _hideTimer; Timer? _flashTimer; FloatingButtonsVisibilityManager._internal(); factory FloatingButtonsVisibilityManager() { _instance ??= FloatingButtonsVisibilityManager._internal(); return _instance!; } Future init() async { final prefs = await SharedPreferences.getInstance(); _isVisible = prefs.getBool(_key) ?? true; _visibleNotifier.value = _isVisible; } bool get isVisible => _isVisible; bool get isFlashing => _isFlashing; ValueNotifier get visibleNotifier => _visibleNotifier; ValueNotifier get flashingNotifier => _flashingNotifier; Future toggle() async { if (_isFlashing) { await _restoreFromFlashing(); return; } _isVisible = !_isVisible; _visibleNotifier.value = _isVisible; final prefs = await SharedPreferences.getInstance(); await prefs.setBool(_key, _isVisible); if (!_isVisible) { _startHideTimer(); } else { _cancelAllTimers(); } } Future _restoreFromFlashing() async { _cancelAllTimers(); _isFlashing = false; _flashingNotifier.value = false; _isVisible = true; _visibleNotifier.value = true; final prefs = await SharedPreferences.getInstance(); await prefs.setBool(_key, true); } void _startHideTimer() { _cancelAllTimers(); _hideTimer = Timer(const Duration(seconds: 5), () { _startFlashing(); }); } void _startFlashing() { _isFlashing = true; _flashingNotifier.value = true; _flashCount = 0; _flashTimer = Timer.periodic(const Duration(seconds: 1), (timer) async { _flashCount++; _flashingNotifier.value = !_flashingNotifier.value; if (_flashCount >= 6) { timer.cancel(); _isFlashing = false; _flashingNotifier.value = false; _isVisible = false; _visibleNotifier.value = false; final prefs = await SharedPreferences.getInstance(); await prefs.setBool(_key, false); } }); } void _cancelAllTimers() { if (_hideTimer != null) { _hideTimer!.cancel(); _hideTimer = null; } if (_flashTimer != null) { _flashTimer!.cancel(); _flashTimer = null; } } void dispose() { _cancelAllTimers(); _visibleNotifier.value = true; _flashingNotifier.value = false; } } /// 收起/恢复悬浮按钮组件 class FloatingButtonsToggleButton extends StatelessWidget { final FloatingButtonsVisibilityManager manager; final bool isDark; const FloatingButtonsToggleButton({ super.key, required this.manager, required this.isDark, }); @override Widget build(BuildContext context) { return ValueListenableBuilder( valueListenable: manager.flashingNotifier, builder: (context, isFlashing, child) { return ValueListenableBuilder( valueListenable: manager.visibleNotifier, builder: (context, isVisible, child) { final shouldShow = isFlashing ? !isFlashing : isVisible; return SizedBox( width: 44, height: 44, child: shouldShow || isFlashing ? Container( decoration: BoxDecoration( color: isDark ? const Color(0xFF2A2A2A) : Colors.white, shape: BoxShape.circle, boxShadow: [ BoxShadow( color: Colors.black.withAlpha(isDark ? 40 : 20), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: Material( color: Colors.transparent, child: InkWell( borderRadius: BorderRadius.circular(22), onTap: () { manager.toggle(); }, child: Center( child: Icon( isFlashing ? Icons.visibility : Icons.visibility_off, color: isFlashing ? AppConstants.primaryColor : (isDark ? Colors.grey[300] : AppConstants.primaryColor), size: 24, ), ), ), ), ) : Material( color: Colors.transparent, child: InkWell( borderRadius: BorderRadius.circular(22), onTap: () { manager.toggle(); }, ), ), ); }, ); }, ); } }