Update RecordingButton design to match UI mockup

Design improvements based on provided mockup:

1. Color Updates:
   - Idle state: Blue (#2196F3) - matches mockup's blue recording button
   - Recording state: Red (#FF5252) - matches mockup's red stop button
   - Disabled state: Light grey (#9E9E9E) for better visibility
   - Processing state: Semi-transparent versions of respective colors

2. Shape Changes:
   - Idle state: Circle (for recording button)
   - Recording state: Rounded rectangle (12px radius) for stop button
   - Smooth transitions between shapes using BoxShape

3. Icon Improvements:
   - Use rounded icons (mic_rounded, stop_rounded) for modern look
   - Adjust icon sizes: recording (40% of button), stop (35% of button)
   - Better proportions matching the design intent

4. Shadow Enhancements:
   - Increased blur radius for idle state (8→12px) for better depth
   - Dynamic shadow based on button state
   - Enhanced spread radius for better visual impact

5. Interactive Elements:
   - InkWell borderRadius adapts to button shape
   - Smooth transitions between circular and rectangular ripple effects

These changes create a modern, professional appearance that matches
common design patterns and provides clear visual feedback for different states.
This commit is contained in:
Max 2025-09-09 14:20:10 +08:00
parent 6146508bed
commit 3e8fe73e27
1 changed files with 19 additions and 14 deletions

View File

@ -168,7 +168,8 @@ class _RecordingButtonState extends State<RecordingButton>
if (_isListening) { if (_isListening) {
await _speechService.stopListening(); await _speechService.stopListening();
} else { } else {
await _speechService.startListening(partialResults: widget.partialResults); await _speechService.startListening(
partialResults: widget.partialResults);
} }
} catch (e) { } catch (e) {
widget.onError?.call(SpeechRecognitionError( widget.onError?.call(SpeechRecognitionError(
@ -190,17 +191,19 @@ class _RecordingButtonState extends State<RecordingButton>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context);
Color buttonColor; Color buttonColor;
if (!widget.enabled || !_isInitialized) { if (!widget.enabled || !_isInitialized) {
buttonColor = widget.disabledColor ?? Colors.grey; buttonColor = widget.disabledColor ?? Colors.grey[400]!;
} else if (_isProcessing) { } else if (_isProcessing) {
buttonColor = (widget.idleColor ?? theme.primaryColor).withValues(alpha: 0.7); buttonColor = _isListening
? (widget.recordingColor ?? const Color(0xFFFF5252))
.withValues(alpha: 0.7)
: (widget.idleColor ?? const Color(0xFF2196F3))
.withValues(alpha: 0.7);
} else if (_isListening) { } else if (_isListening) {
buttonColor = widget.recordingColor ?? Colors.red; buttonColor = widget.recordingColor ?? const Color(0xFFFF5252); //
} else { } else {
buttonColor = widget.idleColor ?? theme.primaryColor; buttonColor = widget.idleColor ?? const Color(0xFF2196F3); //
} }
Widget button = AnimatedBuilder( Widget button = AnimatedBuilder(
@ -213,12 +216,13 @@ class _RecordingButtonState extends State<RecordingButton>
height: widget.size, height: widget.size,
decoration: BoxDecoration( decoration: BoxDecoration(
color: buttonColor, color: buttonColor,
shape: BoxShape.circle, shape: _isListening ? BoxShape.rectangle : BoxShape.circle,
borderRadius: _isListening ? BorderRadius.circular(12) : null,
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
color: buttonColor.withValues(alpha: 0.3), color: buttonColor.withValues(alpha: 0.3),
blurRadius: _isListening ? 20 : 8, blurRadius: _isListening ? 20 : 12,
spreadRadius: _isListening ? 5 : 2, spreadRadius: _isListening ? 5 : 3,
), ),
], ],
), ),
@ -233,12 +237,13 @@ class _RecordingButtonState extends State<RecordingButton>
height: widget.size * 0.4, height: widget.size * 0.4,
child: CircularProgressIndicator( child: CircularProgressIndicator(
strokeWidth: 2, strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(Colors.white), valueColor:
AlwaysStoppedAnimation<Color>(Colors.white),
), ),
) )
: Icon( : Icon(
_isListening ? Icons.stop : Icons.mic, _isListening ? Icons.stop_rounded : Icons.mic_rounded,
size: widget.size * 0.4, size: widget.size * (_isListening ? 0.35 : 0.4),
color: Colors.white, color: Colors.white,
), ),
), ),