Files
wushu/lib/views/home/set/home-set.dart
2026-04-02 07:06:55 +08:00

191 lines
5.7 KiB
Dart

/// 时间: 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<bool> _visibleNotifier = ValueNotifier<bool>(true);
final ValueNotifier<bool> _flashingNotifier = ValueNotifier<bool>(false);
Timer? _hideTimer;
Timer? _flashTimer;
FloatingButtonsVisibilityManager._internal();
factory FloatingButtonsVisibilityManager() {
_instance ??= FloatingButtonsVisibilityManager._internal();
return _instance!;
}
Future<void> init() async {
final prefs = await SharedPreferences.getInstance();
_isVisible = prefs.getBool(_key) ?? true;
_visibleNotifier.value = _isVisible;
}
bool get isVisible => _isVisible;
bool get isFlashing => _isFlashing;
ValueNotifier<bool> get visibleNotifier => _visibleNotifier;
ValueNotifier<bool> get flashingNotifier => _flashingNotifier;
Future<void> 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<void> _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<bool>(
valueListenable: manager.flashingNotifier,
builder: (context, isFlashing, child) {
return ValueListenableBuilder<bool>(
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();
},
),
),
);
},
);
},
);
}
}