Enhance RecordingButton with haptic feedback and debounce
Major UX improvements to RecordingButton: 1. Haptic Feedback (震动效果): - Add HapticFeedback.lightImpact() on button tap - Import flutter/services.dart for haptic support - Provides tactile confirmation for user interactions 2. Debounce Mechanism (防抖): - Add _isProcessing flag to prevent rapid consecutive taps - 300ms cooldown period after each tap - Protects against accidental double-taps and ensures stable operation 3. Enhanced Visual States: - Processing state with semi-transparent color - Loading spinner during async operations - Better visual feedback for different button states 4. Improved Animations: - Trigger scale animation on tap (not just on state change) - Smooth forward/reverse animation cycle - Better visual response to user interactions 5. Better Error Handling: - Proper mounted check before setState - Graceful cleanup with finally block - Prevents memory leaks and state corruption These improvements provide: - Better tactile feedback for users - Prevention of UI race conditions - Clearer visual indication of button states - More responsive and professional user experience
This commit is contained in:
parent
0af37c5b87
commit
6146508bed
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import '../interfaces/speech_recognition_service.dart';
|
||||
import '../yx_asr_service.dart';
|
||||
import '../models/speech_recognition_result.dart';
|
||||
|
|
@ -69,6 +70,7 @@ class _RecordingButtonState extends State<RecordingButton>
|
|||
late SpeechRecognitionService _speechService;
|
||||
bool _isListening = false;
|
||||
bool _isInitialized = false;
|
||||
bool _isProcessing = false; // 防抖标志
|
||||
late AnimationController _animationController;
|
||||
late Animation<double> _scaleAnimation;
|
||||
|
||||
|
|
@ -146,9 +148,23 @@ class _RecordingButtonState extends State<RecordingButton>
|
|||
}
|
||||
|
||||
Future<void> _toggleRecording() async {
|
||||
if (!_isInitialized || !widget.enabled) return;
|
||||
// 防抖检查:如果正在处理中或未初始化或被禁用,则直接返回
|
||||
if (_isProcessing || !_isInitialized || !widget.enabled) return;
|
||||
|
||||
// 设置处理中标志,防止重复点击
|
||||
setState(() {
|
||||
_isProcessing = true;
|
||||
});
|
||||
|
||||
try {
|
||||
// 触觉反馈
|
||||
await HapticFeedback.lightImpact();
|
||||
|
||||
// 播放点击动画
|
||||
_animationController.forward().then((_) {
|
||||
_animationController.reverse();
|
||||
});
|
||||
|
||||
if (_isListening) {
|
||||
await _speechService.stopListening();
|
||||
} else {
|
||||
|
|
@ -160,6 +176,15 @@ class _RecordingButtonState extends State<RecordingButton>
|
|||
errorMsg: '切换录音状态失败: $e',
|
||||
errorCode: null,
|
||||
));
|
||||
} finally {
|
||||
// 延迟重置处理标志,确保有足够的防抖时间
|
||||
Future.delayed(const Duration(milliseconds: 300), () {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isProcessing = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -170,6 +195,8 @@ class _RecordingButtonState extends State<RecordingButton>
|
|||
Color buttonColor;
|
||||
if (!widget.enabled || !_isInitialized) {
|
||||
buttonColor = widget.disabledColor ?? Colors.grey;
|
||||
} else if (_isProcessing) {
|
||||
buttonColor = (widget.idleColor ?? theme.primaryColor).withValues(alpha: 0.7);
|
||||
} else if (_isListening) {
|
||||
buttonColor = widget.recordingColor ?? Colors.red;
|
||||
} else {
|
||||
|
|
@ -200,11 +227,20 @@ class _RecordingButtonState extends State<RecordingButton>
|
|||
child: InkWell(
|
||||
borderRadius: BorderRadius.circular(widget.size / 2),
|
||||
onTap: _toggleRecording,
|
||||
child: Icon(
|
||||
_isListening ? Icons.stop : Icons.mic,
|
||||
size: widget.size * 0.4,
|
||||
color: Colors.white,
|
||||
),
|
||||
child: _isProcessing
|
||||
? SizedBox(
|
||||
width: widget.size * 0.4,
|
||||
height: widget.size * 0.4,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
|
||||
),
|
||||
)
|
||||
: Icon(
|
||||
_isListening ? Icons.stop : Icons.mic,
|
||||
size: widget.size * 0.4,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in New Issue