完成远程遥控页面的优化,包括 折叠功能栏 点击振动反馈 ,急停的读秒进度条 ,左右的振动反馈 ,锁屏的功能按钮的开发(禁用上下左右的滑轮)

This commit is contained in:
2026-03-24 17:09:12 +08:00
parent f7523a943d
commit 8772b1cb43
17 changed files with 525 additions and 119 deletions

View File

@@ -2,6 +2,7 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:vibration/vibration.dart';
enum SliderAxis { horizontal, vertical }
@@ -41,25 +42,91 @@ class _CCExpandSliderState extends State<CCExpandSlider> {
double _alignmentValue = 0.0;
bool _isExpanded = false;
Timer? _tickTimer;
int? _lastVibrationState;
Timer? _continuousVibrateTimer;
bool _hasCheckedVibrator = false;
bool? _hasVibrator;
@override
void initState() {
super.initState();
_checkVibrator();
}
Future<void> _checkVibrator() async {
_hasVibrator = await Vibration.hasVibrator();
setState(() {
_hasCheckedVibrator = true;
});
debugPrint('🔍 震动器检测:${_hasVibrator == true ? "有" : "无"}');
}
@override
void dispose() {
_tickTimer?.cancel();
_continuousVibrateTimer?.cancel();
super.dispose();
}
Future<void> _triggerVibration(int duration, String reason) async {
if (!_hasCheckedVibrator) return;
try {
if (_hasVibrator == true) {
await Vibration.vibrate(duration: duration);
debugPrint('📳 $reason - 震动 ${duration}ms');
} else {
debugPrint('⚠️ $reason - 设备不支持震动');
}
} catch (e) {
debugPrint('❌ $reason - 震动失败:$e');
}
}
void _vibrate(int state) {
if (state != _lastVibrationState) {
_triggerVibration(50, '状态变化');
_lastVibrationState = state;
}
}
void _startContinuousVibration() {
_continuousVibrateTimer?.cancel();
_continuousVibrateTimer = Timer.periodic(const Duration(milliseconds: 300), (_) {
if (!_isExpanded) return;
if (_alignmentValue < -0.5 || _alignmentValue > 0.5) {
_triggerVibration(30, '连续震动');
}
});
}
void _stopContinuousVibration() {
_continuousVibrateTimer?.cancel();
_continuousVibrateTimer = null;
}
void _startTicking() {
_tickTimer?.cancel();
_tickTimer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
if (!_isExpanded) return;
int currentState;
if (_alignmentValue < -0.5) {
currentState = -1;
widget.onStart?.call();
} else if (_alignmentValue > 0.5) {
currentState = 1;
widget.onEnd?.call();
} else {
currentState = 0;
widget.onCenter?.call();
}
_vibrate(currentState);
});
_startContinuousVibration();
}
void _safeSetExpanded(bool expanded) {
@@ -70,6 +137,8 @@ class _CCExpandSliderState extends State<CCExpandSlider> {
if (!expanded) {
_alignmentValue = 0.0;
_tickTimer?.cancel();
_continuousVibrateTimer?.cancel();
_lastVibrationState = null;
}
});
if (expanded) _startTicking();
@@ -88,7 +157,13 @@ class _CCExpandSliderState extends State<CCExpandSlider> {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onPanDown: (_) => _safeSetExpanded(true),
onPanDown: (_) {
debugPrint('👆 按下');
if (_hasCheckedVibrator) {
_triggerVibration(40, '按下');
}
_safeSetExpanded(true);
},
onPanUpdate: (details) {
if (!_isExpanded) return;
setState(() {
@@ -97,16 +172,23 @@ class _CCExpandSliderState extends State<CCExpandSlider> {
});
},
onPanEnd: (_) {
debugPrint('✋ 松开');
if (widget.isSpring) widget.onCenter?.call();
HapticFeedback.lightImpact();
if (_hasCheckedVibrator) {
_triggerVibration(40, '松开');
}
_lastVibrationState = null;
_stopContinuousVibration();
_safeSetExpanded(false);
},
onPanCancel: () {
debugPrint('❌ 取消');
_safeSetExpanded(false);
},
onPanCancel: () => _safeSetExpanded(false),
child: Stack(
alignment: Alignment.center,
clipBehavior: Clip.none,
children: [
// 1. 轨道背景:从中向外展开
AnimatedContainer(
duration: const Duration(milliseconds: 200),
curve: Curves.easeOutCubic,
@@ -120,10 +202,8 @@ class _CCExpandSliderState extends State<CCExpandSlider> {
child: _buildSegmentedContent(isVertical, maxLength, minLength),
),
// 2. 核心修改:文字位置固定逻辑
// 我们用一个和“缩起状态”一样大的 SizedBox 作为参考
if (!_isExpanded)
IgnorePointer( // 防止文字遮挡点击
IgnorePointer(
child: SizedBox(
width: minLength,
height: minLength,
@@ -132,7 +212,7 @@ class _CCExpandSliderState extends State<CCExpandSlider> {
alignment: Alignment.center,
children: [
Positioned(
bottom: -22, // 这里的 -22 是相对于“缩起时正方形”的底部
bottom: -22,
child: Text(
widget.label,
style: TextStyle(
@@ -220,4 +300,4 @@ class _CCExpandSliderState extends State<CCExpandSlider> {
colorFilter: ColorFilter.mode(color, BlendMode.srcIn),
);
}
}
}