增加悬浮图标的声波动画效果

This commit is contained in:
2025-08-12 17:40:39 +08:00
parent 4035804b73
commit 15680677fc
6 changed files with 153 additions and 36 deletions

View File

@@ -1,9 +1,9 @@
import 'package:ai_chat_assistant/services/vehicle_state_service.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../services/message_service.dart';
import '../screens/full_screen.dart';
import '../screens/part_screen.dart';
import 'floating_icon_with_wave.dart';
class FloatingIcon extends StatefulWidget {
const FloatingIcon({super.key});
@@ -12,15 +12,28 @@ class FloatingIcon extends StatefulWidget {
State<FloatingIcon> createState() => _FloatingIconState();
}
class _FloatingIconState extends State<FloatingIcon> {
class _FloatingIconState extends State<FloatingIcon>
with SingleTickerProviderStateMixin {
Offset _position = const Offset(10, 120);
final iconSize = 80.0;
bool _isShowPartScreen = false;
late AnimationController _waveAnimationController;
@override
void initState() {
super.initState();
// VehicleStateService();
_waveAnimationController = AnimationController(
duration: const Duration(milliseconds: 1000),
vsync: this,
);
}
@override
void dispose() {
_waveAnimationController.dispose();
super.dispose();
}
void _showPartScreen() {
@@ -67,13 +80,30 @@ class _FloatingIconState extends State<FloatingIcon> {
right: _position.dx,
child: Consumer<MessageService>(
builder: (context, messageService, child) {
// 立即响应录音状态变化,控制动画
WidgetsBinding.instance.addPostFrameCallback((_) {
if (messageService.isRecording) {
if (!_waveAnimationController.isAnimating) {
_waveAnimationController.repeat();
}
} else {
if (_waveAnimationController.isAnimating) {
_waveAnimationController.stop();
}
}
});
return GestureDetector(
onTap: _showFullScreen,
onLongPress: () async {
_showPartScreen();
// 立即启动动画
_waveAnimationController.repeat();
await messageService.startVoiceInput();
},
onLongPressUp: () async {
// 立即停止动画
_waveAnimationController.stop();
await messageService.stopAndProcessVoiceInput();
final hasMessage = messageService.messages.isNotEmpty;
if (!hasMessage) {
@@ -81,13 +111,17 @@ class _FloatingIconState extends State<FloatingIcon> {
}
},
onPanUpdate: (details) => _updatePosition(details.delta),
child: Image.asset(
messageService.isRecording
? 'assets/images/ai2.png'
: 'assets/images/ai1.png',
width: iconSize,
height: iconSize,
),
child: messageService.isRecording
? FloatingIconWithWave(
animationController: _waveAnimationController,
iconSize: iconSize,
waveColor: Colors.white,
)
: Image.asset(
'assets/images/ai1_hd.png',
width: iconSize,
height: iconSize,
),
);
},
),