完成远程遥控页面的优化,包括 折叠功能栏 点击振动反馈 ,急停的读秒进度条 ,左右的振动反馈 ,锁屏的功能按钮的开发(禁用上下左右的滑轮)
This commit is contained in:
@@ -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),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user