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.
This commit is contained in:
parent
ac234d99ec
commit
aba8b44ab8
|
|
@ -169,7 +169,8 @@ class _RecordingButtonState extends State<RecordingButton>
|
|||
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<RecordingButton>
|
|||
|
||||
@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<Color>(Colors.white),
|
||||
),
|
||||
)
|
||||
: Icon(
|
||||
_isListening ? Icons.stop_rounded : Icons.mic_rounded,
|
||||
size: widget.size * (_isListening ? 0.35 : 0.4),
|
||||
color: Colors.white,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in New Issue