From aba8b44ab8fcf3bd97f584b1c5ecd60990a4ab5b Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 9 Sep 2025 15:08:35 +0800 Subject: [PATCH] Update RecordingButton design with new visual style Major design changes based on user requirements: 1. Background Style Changes: - Remove solid color background and shadows - Use semi-transparent background (alpha: 0.12) for subtle visual feedback - Maintain circular shape for both states 2. Icon Improvements: - Increase icon size to 55% of button size for better visibility - Use color-coded icons: blue for idle, red for recording - Remove white icon color, use theme-based colors instead 3. Loading Indicator Enhancement: - Show CircularProgressIndicator during both processing and listening states - Position indicator as overlay using Stack layout - Maintain white color for progress indicator for contrast 4. Color Logic Simplification: - Consolidate color logic into single iconColor variable - Remove complex state-based color transitions - Use consistent color scheme: blue (#2196F3) idle, red (#FF5252) recording - Darker disabled color (#212121) for better contrast 5. Layout Structure Update: - Replace Transform.scale animation wrapper with direct Container - Use Stack for layering icon and progress indicator - Positioned widgets for precise control over element placement This creates a more modern, minimalist design with better visual hierarchy and improved accessibility through higher contrast ratios. --- lib/src/widgets/recording_button.dart | 85 ++++++++++++++------------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/lib/src/widgets/recording_button.dart b/lib/src/widgets/recording_button.dart index 1453446..d7011b9 100644 --- a/lib/src/widgets/recording_button.dart +++ b/lib/src/widgets/recording_button.dart @@ -169,7 +169,8 @@ class _RecordingButtonState extends State await _speechService.stopListening(); } else { await _speechService.startListening( - partialResults: widget.partialResults); + partialResults: widget.partialResults, + ); } } catch (e) { widget.onError?.call(SpeechRecognitionError( @@ -191,60 +192,60 @@ class _RecordingButtonState extends State @override Widget build(BuildContext context) { - Color buttonColor; + Color iconColor; if (!widget.enabled || !_isInitialized) { - buttonColor = widget.disabledColor ?? Colors.grey[400]!; - } else if (_isProcessing) { - buttonColor = _isListening - ? (widget.recordingColor ?? const Color(0xFFFF5252)) - .withValues(alpha: 0.7) - : (widget.idleColor ?? const Color(0xFF2196F3)) - .withValues(alpha: 0.7); - } else if (_isListening) { - buttonColor = widget.recordingColor ?? const Color(0xFFFF5252); // 红色停止按钮 + iconColor = widget.disabledColor ?? Colors.grey[850]!; } else { - buttonColor = widget.idleColor ?? const Color(0xFF2196F3); // 蓝色录音按钮 + iconColor = _isListening + ? (widget.recordingColor ?? const Color(0xFFFF5252)) + : (widget.idleColor ?? const Color(0xFF2196F3)); } Widget button = AnimatedBuilder( animation: _scaleAnimation, builder: (context, child) { - return Transform.scale( - scale: _scaleAnimation.value, - child: Container( - width: widget.size, - height: widget.size, - decoration: BoxDecoration( - color: buttonColor, - shape: BoxShape.circle, - boxShadow: [ - BoxShadow( - color: buttonColor.withValues(alpha: 0.3), - blurRadius: _isListening ? 20 : 12, - spreadRadius: _isListening ? 5 : 3, - ), - ], - ), - child: Material( - color: Colors.transparent, - child: InkWell( - borderRadius: BorderRadius.circular(widget.size / 2), - onTap: _toggleRecording, - child: _isProcessing - ? SizedBox( - width: widget.size * 0.4, - height: widget.size * 0.4, + return Container( + width: widget.size, + height: widget.size, + decoration: BoxDecoration( + color: iconColor.withValues(alpha: 0.12), + shape: BoxShape.circle, + ), + child: Material( + color: Colors.transparent, + child: InkWell( + borderRadius: BorderRadius.circular(widget.size / 2), + onTap: _toggleRecording, + child: Stack( + children: [ + Positioned( + left: 0, + right: 0, + bottom: 0, + top: 0, + child: Icon( + _isListening ? Icons.stop_rounded : Icons.mic_rounded, + size: widget.size * 0.55, + color: iconColor, + ), + ), + 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(Colors.white), ), - ) - : Icon( - _isListening ? Icons.stop_rounded : Icons.mic_rounded, - size: widget.size * (_isListening ? 0.35 : 0.4), - color: Colors.white, ), + ) + ], ), ), ),