使用 assets_util 来管理 assets

This commit is contained in:
2025-09-19 11:40:38 +08:00
parent b84899ece3
commit 0509096925
12 changed files with 50 additions and 42 deletions

3
.fvmrc Normal file
View File

@@ -0,0 +1,3 @@
{
"flutter": "3.27.4"
}

5
.gitignore vendored
View File

@@ -44,4 +44,7 @@ app.*.map.json
/android/app/profile /android/app/profile
/android/app/release /android/app/release
.vscode/ .vscode/
# FVM Version Cache
.fvm/

View File

@@ -23,4 +23,7 @@ export 'models/vehicle_status_info.dart';
export 'enums/vehicle_command_type.dart'; export 'enums/vehicle_command_type.dart';
export 'enums/message_status.dart'; export 'enums/message_status.dart';
export 'enums/message_service_state.dart'; export 'enums/message_service_state.dart';
// utils
export 'utils/assets_util.dart';

View File

@@ -8,6 +8,7 @@ import 'models/vehicle_cmd.dart';
/// 车辆命令处理器抽象类 /// 车辆命令处理器抽象类
abstract class VehicleCommandHandler { abstract class VehicleCommandHandler {
AIChatCommandCubit? commandCubit; AIChatCommandCubit? commandCubit;
/// 执行车辆控制命令 /// 执行车辆控制命令
Future<(bool, Map<String, dynamic>?)> executeCommand(VehicleCommand command); Future<(bool, Map<String, dynamic>?)> executeCommand(VehicleCommand command);
} }
@@ -48,5 +49,4 @@ class AIChatAssistantManager {
_commandCubit?.close(); _commandCubit?.close();
_commandCubit = null; _commandCubit = null;
} }
} }

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../widgets/floating_icon.dart'; import '../widgets/floating_icon.dart';
import '../utils/assets_util.dart';
class MainScreen extends StatefulWidget { class MainScreen extends StatefulWidget {
const MainScreen({super.key}); const MainScreen({super.key});
@@ -26,9 +27,9 @@ class _MainScreenState extends State<MainScreen> {
body: Stack( body: Stack(
children: [ children: [
Container( Container(
decoration: const BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: AssetImage('assets/images/bg.jpg', package: 'ai_chat_assistant'), image: AssetsUtil.getImage('bg.jpg'),
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
), ),

View File

@@ -5,6 +5,7 @@ import '../screens/full_screen.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../services/message_service.dart'; import '../services/message_service.dart';
import '../widgets/gradient_background.dart'; import '../widgets/gradient_background.dart';
import '../utils/assets_util.dart';
class PartScreen extends StatefulWidget { class PartScreen extends StatefulWidget {
final VoidCallback? onHide; final VoidCallback? onHide;
@@ -202,11 +203,10 @@ class _PartScreenState extends State<PartScreen> {
top: 6, top: 6,
right: 6, right: 6,
child: IconButton( child: IconButton(
icon: Image.asset( icon: AssetsUtil.getImageWidget(
'assets/images/open_in_full.png', 'open_in_full.png',
width: 24, width: 24,
height: 24, height: 24,
package: 'ai_chat_assistant',
), ),
onPressed: _openFullScreen, onPressed: _openFullScreen,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../utils/assets_util.dart';
class AssistantAvatar extends StatelessWidget { class AssistantAvatar extends StatelessWidget {
final double width; final double width;
@@ -15,10 +16,9 @@ class AssistantAvatar extends StatelessWidget {
return SizedBox( return SizedBox(
width: width, width: width,
height: height, height: height,
child: Image.asset( child: AssetsUtil.getImageWidget(
'assets/images/avatar.png', 'avatar.png',
fit: BoxFit.contain, fit: BoxFit.contain,
package: 'ai_chat_assistant',
), ),
); );
} }

View File

@@ -9,6 +9,7 @@ import 'package:provider/provider.dart';
import '../services/message_service.dart'; import '../services/message_service.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import '../utils/assets_util.dart';
class ChatBubble extends StatefulWidget { class ChatBubble extends StatefulWidget {
final ChatMessage message; final ChatMessage message;
@@ -108,7 +109,7 @@ class _ChatBubbleState extends State<ChatBubble> {
case MessageStatus.listening: case MessageStatus.listening:
case MessageStatus.recognizing: case MessageStatus.recognizing:
case MessageStatus.thinking: case MessageStatus.thinking:
icon = RotatingImage(imagePath: 'assets/images/thinking_circle.png'); icon = RotatingImage(imagePath: 'thinking_circle.png');
color = Colors.white; color = Colors.white;
break; break;
case MessageStatus.executing: case MessageStatus.executing:
@@ -123,11 +124,10 @@ class _ChatBubbleState extends State<ChatBubble> {
break; break;
case MessageStatus.completed: case MessageStatus.completed:
case MessageStatus.success: case MessageStatus.success:
icon = Image.asset( icon = AssetsUtil.getImageWidget(
'assets/images/checked.png', 'checked.png',
width: 20, width: 20,
height: 20, height: 20,
package: 'ai_chat_assistant',
); );
color = Colors.white; color = Colors.white;
break; break;
@@ -306,8 +306,7 @@ class _ChatBubbleState extends State<ChatBubble> {
}, },
child: Padding( child: Padding(
padding: const EdgeInsets.only(left: 12), padding: const EdgeInsets.only(left: 12),
child: Image.asset('assets/images/copy.png', child: AssetsUtil.getImageWidget('copy.png',
package: 'ai_chat_assistant',
width: 22, width: 22,
height: 22), height: 22),
), ),
@@ -322,12 +321,10 @@ class _ChatBubbleState extends State<ChatBubble> {
child: Padding( child: Padding(
padding: const EdgeInsets.only(left: 12), padding: const EdgeInsets.only(left: 12),
child: _liked child: _liked
? Image.asset('assets/images/liked2.png', ? AssetsUtil.getImageWidget('liked2.png',
package: 'ai_chat_assistant',
width: 22, width: 22,
height: 22) height: 22)
: Image.asset('assets/images/liked1.png', : AssetsUtil.getImageWidget('liked1.png',
package: 'ai_chat_assistant',
width: 22, width: 22,
height: 22), height: 22),
), ),
@@ -342,12 +339,10 @@ class _ChatBubbleState extends State<ChatBubble> {
child: Padding( child: Padding(
padding: const EdgeInsets.only(left: 12), padding: const EdgeInsets.only(left: 12),
child: _disliked child: _disliked
? Image.asset('assets/images/disliked2.png', ? AssetsUtil.getImageWidget('disliked2.png',
package: 'ai_chat_assistant',
width: 22, width: 22,
height: 22) height: 22)
: Image.asset('assets/images/disliked1.png', : AssetsUtil.getImageWidget('disliked1.png',
package: 'ai_chat_assistant',
width: 22, width: 22,
height: 22)), height: 22)),
), ),

View File

@@ -5,6 +5,7 @@ import 'package:provider/provider.dart';
import '../services/message_service.dart'; import '../services/message_service.dart';
import '../utils/common_util.dart'; import '../utils/common_util.dart';
import 'large_audio_wave.dart'; import 'large_audio_wave.dart';
import '../utils/assets_util.dart';
class ChatFooter extends StatefulWidget { class ChatFooter extends StatefulWidget {
final VoidCallback? onClear; final VoidCallback? onClear;
@@ -48,8 +49,8 @@ class _ChatFooterState extends State<ChatFooter>
padding: const EdgeInsets.only(left: 16, bottom: 12), padding: const EdgeInsets.only(left: 16, bottom: 12),
child: GestureDetector( child: GestureDetector(
onTap: widget.onClear, onTap: widget.onClear,
child: Image.asset( child: AssetsUtil.getImageWidget(
'assets/images/delete.png',package: 'ai_chat_assistant', 'delete.png',
width: 24, width: 24,
height: 24, height: 24,
), ),
@@ -138,8 +139,8 @@ class _ChatFooterState extends State<ChatFooter>
onTap: () { onTap: () {
}, },
child: Image.asset( child: AssetsUtil.getImageWidget(
'assets/images/keyboard_mini.png',package: 'ai_chat_assistant', 'keyboard_mini.png',
width: 24, width: 24,
height: 24, height: 24,
), ),

View File

@@ -6,6 +6,7 @@ import '../screens/part_screen.dart';
import 'floating_icon_with_wave.dart'; import 'floating_icon_with_wave.dart';
import 'dart:async'; import 'dart:async';
import 'package:basic_intl/intl.dart'; import 'package:basic_intl/intl.dart';
import '../utils/assets_util.dart';
class FloatingIcon extends StatefulWidget { class FloatingIcon extends StatefulWidget {
const FloatingIcon({super.key}); const FloatingIcon({super.key});
@@ -35,13 +36,13 @@ class _FloatingIconState extends State<FloatingIcon> with TickerProviderStateMix
// 图片切换相关 // 图片切换相关
int _imageIndex = 0; int _imageIndex = 0;
late final List<String> _iconImages = [ late final List<String> _iconImages = [
'assets/images/ai1_hd.png', 'ai1_hd.png',
'assets/images/ai0_hd.png', 'ai0_hd.png',
]; ];
late final List<String> _iconImagesEn = [ late final List<String> _iconImagesEn = [
'assets/images/ai1_hd_en.png', 'ai1_hd_en.png',
'assets/images/ai0_hd_en.png', 'ai0_hd_en.png',
]; ];
@override @override
@@ -96,7 +97,7 @@ class _FloatingIconState extends State<FloatingIcon> with TickerProviderStateMix
// 显示全屏界面 // 显示全屏界面
void _showFullScreen() async { void _showFullScreen() async {
_hidePartScreen(); _hidePartScreen();
final messageService = context.read<MessageService>(); final messageService = MessageService.instance;
await Navigator.of(context).push( await Navigator.of(context).push(
MaterialPageRoute( MaterialPageRoute(
@@ -170,7 +171,10 @@ class _FloatingIconState extends State<FloatingIcon> with TickerProviderStateMix
// } // }
// }); // });
return ChangeNotifierProvider(create: (_) => MessageService(), child: _buildFloatingIcon()); return ChangeNotifierProvider.value(
value: MessageService.instance,
child: _buildFloatingIcon(),
);
} }
Widget _buildFloatingIcon() { Widget _buildFloatingIcon() {
@@ -249,13 +253,12 @@ class _FloatingIconState extends State<FloatingIcon> with TickerProviderStateMix
iconSize: iconSize, iconSize: iconSize,
waveColor: Colors.white, waveColor: Colors.white,
) )
: Image.asset( : AssetsUtil.getImageWidget(
Intl.getCurrentLocale().startsWith('zh') Intl.getCurrentLocale().startsWith('zh')
? _iconImages[_imageIndex] ? _iconImages[_imageIndex]
: _iconImagesEn[_imageIndex], : _iconImagesEn[_imageIndex],
width: iconSize, width: iconSize,
height: iconSize, height: iconSize,
package: 'ai_chat_assistant',
), ),
), ),
); );

View File

@@ -32,12 +32,11 @@ class FloatingIconWithWave extends StatelessWidget {
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
// 背景图片 // 背景图片
Image.asset( AssetsUtil.getImageWidget(
'assets/images/ai_hd_clean.png', 'ai_hd_clean.png',
width: iconSize, width: iconSize,
height: iconSize, height: iconSize,
fit: BoxFit.contain, fit: BoxFit.contain,
package: AssetsUtil.packageName
), ),
// 声波动画距离底部13px的位置 // 声波动画距离底部13px的位置
Positioned( Positioned(

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../utils/assets_util.dart';
class RotatingImage extends StatefulWidget { class RotatingImage extends StatefulWidget {
final String imagePath; final String imagePath;
@@ -42,11 +43,10 @@ class _RotatingImageState extends State<RotatingImage>
Widget build(BuildContext context) { Widget build(BuildContext context) {
return RotationTransition( return RotationTransition(
turns: _controller, turns: _controller,
child: Image.asset( child: AssetsUtil.getImageWidget(
widget.imagePath, widget.imagePath,
width: widget.size, width: widget.size,
height: widget.size, height: widget.size,
package: widget.package, // 使用传入的package参数
), ),
); );
} }