Compare commits

..

No commits in common. "aba8b44ab8fcf3bd97f584b1c5ecd60990a4ab5b" and "0af37c5b879c25c4f1700dd8cf3a7d14887cbea2" have entirely different histories.

1 changed files with 35 additions and 76 deletions

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../interfaces/speech_recognition_service.dart'; import '../interfaces/speech_recognition_service.dart';
import '../yx_asr_service.dart'; import '../yx_asr_service.dart';
import '../models/speech_recognition_result.dart'; import '../models/speech_recognition_result.dart';
@ -70,7 +69,6 @@ class _RecordingButtonState extends State<RecordingButton>
late SpeechRecognitionService _speechService; late SpeechRecognitionService _speechService;
bool _isListening = false; bool _isListening = false;
bool _isInitialized = false; bool _isInitialized = false;
bool _isProcessing = false; //
late AnimationController _animationController; late AnimationController _animationController;
late Animation<double> _scaleAnimation; late Animation<double> _scaleAnimation;
@ -148,29 +146,13 @@ class _RecordingButtonState extends State<RecordingButton>
} }
Future<void> _toggleRecording() async { Future<void> _toggleRecording() async {
// if (!_isInitialized || !widget.enabled) return;
if (_isProcessing || !_isInitialized || !widget.enabled) return;
//
setState(() {
_isProcessing = true;
});
try { try {
//
await HapticFeedback.lightImpact();
//
_animationController.forward().then((_) {
_animationController.reverse();
});
if (_isListening) { if (_isListening) {
await _speechService.stopListening(); await _speechService.stopListening();
} else { } else {
await _speechService.startListening( await _speechService.startListening(partialResults: widget.partialResults);
partialResults: widget.partialResults,
);
} }
} catch (e) { } catch (e) {
widget.onError?.call(SpeechRecognitionError( widget.onError?.call(SpeechRecognitionError(
@ -178,74 +160,51 @@ class _RecordingButtonState extends State<RecordingButton>
errorMsg: '切换录音状态失败: $e', errorMsg: '切换录音状态失败: $e',
errorCode: null, errorCode: null,
)); ));
} finally {
//
Future.delayed(const Duration(milliseconds: 300), () {
if (mounted) {
setState(() {
_isProcessing = false;
});
}
});
} }
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Color iconColor; final theme = Theme.of(context);
Color buttonColor;
if (!widget.enabled || !_isInitialized) { if (!widget.enabled || !_isInitialized) {
iconColor = widget.disabledColor ?? Colors.grey[850]!; buttonColor = widget.disabledColor ?? Colors.grey;
} else if (_isListening) {
buttonColor = widget.recordingColor ?? Colors.red;
} else { } else {
iconColor = _isListening buttonColor = widget.idleColor ?? theme.primaryColor;
? (widget.recordingColor ?? const Color(0xFFFF5252))
: (widget.idleColor ?? const Color(0xFF2196F3));
} }
Widget button = AnimatedBuilder( Widget button = AnimatedBuilder(
animation: _scaleAnimation, animation: _scaleAnimation,
builder: (context, child) { builder: (context, child) {
return Container( return Transform.scale(
width: widget.size, scale: _scaleAnimation.value,
height: widget.size, child: Container(
decoration: BoxDecoration( width: widget.size,
color: iconColor.withValues(alpha: 0.12), height: widget.size,
shape: BoxShape.circle, decoration: BoxDecoration(
), color: buttonColor,
child: Material( shape: BoxShape.circle,
color: Colors.transparent, boxShadow: [
child: InkWell( BoxShadow(
borderRadius: BorderRadius.circular(widget.size / 2), color: buttonColor.withValues(alpha: 0.3),
onTap: _toggleRecording, blurRadius: _isListening ? 20 : 8,
child: Stack( spreadRadius: _isListening ? 5 : 2,
children: [ ),
Positioned( ],
left: 0, ),
right: 0, child: Material(
bottom: 0, color: Colors.transparent,
top: 0, child: InkWell(
child: Icon( borderRadius: BorderRadius.circular(widget.size / 2),
_isListening ? Icons.stop_rounded : Icons.mic_rounded, onTap: _toggleRecording,
size: widget.size * 0.55, child: Icon(
color: iconColor, _isListening ? Icons.stop : Icons.mic,
), size: widget.size * 0.4,
), color: Colors.white,
if (_isProcessing || _isListening) ),
Positioned(
left: 0,
right: 0,
bottom: 0,
top: 0,
child: SizedBox(
width: widget.size,
height: widget.size,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor:
AlwaysStoppedAnimation<Color>(Colors.white),
),
),
)
],
), ),
), ),
), ),