From 94cb890e6e7ab167c830cb1ae844c4df0114f486 Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Wed, 20 Aug 2025 23:56:00 +0800 Subject: [PATCH] =?UTF-8?q?perf(home):=20=E4=BC=98=E5=8C=96=E9=A6=96?= =?UTF-8?q?=E9=A1=B5=E5=B8=83=E5=B1=80=E5=92=8C=E5=9B=BE=E7=89=87=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 预缓存图片资源以减少加载延迟,重构布局结构使热门AI体验区域固定在底部,并为自适应图片组件添加重绘边界以优化动画性能 --- lib/modules/home/views/home_view.dart | 186 +++++++++++++------------- 1 file changed, 96 insertions(+), 90 deletions(-) diff --git a/lib/modules/home/views/home_view.dart b/lib/modules/home/views/home_view.dart index 8506a7337..1ff190e8f 100644 --- a/lib/modules/home/views/home_view.dart +++ b/lib/modules/home/views/home_view.dart @@ -72,6 +72,11 @@ class HomeView extends GetView { @override Widget build(BuildContext context) { + // 预缓存图片 + precacheImage( + const AssetImage('assets/images/headphone_new3.png'), context); + precacheImage( + const AssetImage('assets/images/headphone_new4.png'), context); final bool isDarkMode = Theme.of(context).brightness == Brightness.dark; return Scaffold( backgroundColor: isDarkMode ? Colors.black : const Color(0xFFF9FAFC), @@ -83,77 +88,79 @@ class HomeView extends GetView { children: [ // 顶部标题栏 _buildAppBar(isDarkMode), - - // 可变高度的顶部图片区域 - Obx(() => _buildAdaptiveEarbudsImage()), - - SizedBox(height: 20.h), - - // 设备状态卡片 - 使用 AnimatedContainer 实现平滑过渡 - IntroStepBuilder( - group: 'home', - order: 1, - onWidgetLoad: () { - controller.noviceGuideService.startHomeGuide(); - }, - overlayBuilder: (params) { - return IntroOverlayBuilder.aiBuilder( - params, - '欢迎使用Voitrans!首先,让我们唤醒你的专属 AI—— 小言', - onNext: () { - controller.noviceGuideService.startWakeupListen(); - }, - ); - }, - builder: (BuildContext context, GlobalKey key) => SizedBox( - key: key, - child: _buildAnimatedDeviceStatusCard(isDarkMode), - ), - ), - - SizedBox(height: 20.h), - - IntroStepBuilder( - group: 'home', - order: 2, - getOverlayPosition: ({ - required Offset offset, - required Size screenSize, - required Size size, - }) { - return OverlayPosition( - top: 200.h, - width: screenSize.width, - crossAxisAlignment: CrossAxisAlignment.end, - ); - }, - overlayBuilder: (params) { - return Obx( - () => IntroOverlayBuilder.homeBuilder( - params, - controller.noviceGuideService.isWakeup.value, - onNext: () { - controller.noviceGuideService.closeWakeupListen(); - }, - ), - ); - }, - builder: (BuildContext context, GlobalKey key) => SizedBox( - key: key, - ), - ), - - // 热门AI体验 - 使用 Expanded 确保始终在可视范围内 + // 可变高度的顶部图片区域 - 使用Expanded让它占用剩余空间 Expanded( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, children: [ - _buildSectionTitle(isDarkMode), - SizedBox(height: 16.h), - Expanded(child: _buildPremiumAILayout()), + Obx(() => _buildAdaptiveEarbudsImage()), + SizedBox(height: 20.h), + // 设备状态卡片 + IntroStepBuilder( + group: 'home', + order: 1, + onWidgetLoad: () { + controller.noviceGuideService.startHomeGuide(); + }, + overlayBuilder: (params) { + return IntroOverlayBuilder.aiBuilder( + params, + '欢迎使用Voitrans!首先,让我们唤醒你的专属 AI—— 小言', + onNext: () { + controller.noviceGuideService.startWakeupListen(); + }, + ); + }, + builder: (BuildContext context, GlobalKey key) => + SizedBox( + key: key, + child: _buildAnimatedDeviceStatusCard(isDarkMode), + ), + ), + SizedBox(height: 20.h), + IntroStepBuilder( + group: 'home', + order: 2, + getOverlayPosition: ({ + required Offset offset, + required Size screenSize, + required Size size, + }) { + return OverlayPosition( + top: 200.h, + width: screenSize.width, + crossAxisAlignment: CrossAxisAlignment.end, + ); + }, + overlayBuilder: (params) { + return Obx( + () => IntroOverlayBuilder.homeBuilder( + params, + controller.noviceGuideService.isWakeup.value, + onNext: () { + controller.noviceGuideService.closeWakeupListen(); + }, + ), + ); + }, + builder: (BuildContext context, GlobalKey key) => + SizedBox( + key: key, + ), + ), ], ), ), + // 热门AI体验 - 固定在底部,基于内容的固定高度 + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, // 重要:让高度基于内容 + children: [ + _buildSectionTitle(isDarkMode), + SizedBox(height: 16.h), + // 给AI布局一个固定的高度,或者让它基于内容自适应 + _buildPremiumAILayout(), + ], + ), ], ), ), @@ -203,40 +210,39 @@ class HomeView extends GetView { ); } - - // 自适应高度的耳机图片 - 根据设备连接状态动态调整高度 + // 在自适应图片组件中添加RepaintBoundary Widget _buildAdaptiveEarbudsImage() { final bool isDarkMode = Get.isDarkMode; - // 根据设备连接状态调整图片高度 - // 已连接时高度较小,为设备信息让出空间;未连接时高度较大 - final double imageHeight = controller.isFullyConnectedRx.value ? 160.h : 220.h; - - return AnimatedContainer( - duration: const Duration(milliseconds: 500), // 平滑过渡动画 - curve: Curves.easeInOut, - height: imageHeight, - child: PageView( - children: [ - Center( - child: ClipRRect( - borderRadius: BorderRadius.circular(16.r), - child: Image.asset( - isDarkMode - ? 'assets/images/headphone_new3.png' - : 'assets/images/headphone_new4.png', - height: imageHeight, - fit: BoxFit.contain, + final double imageHeight = + controller.isFullyConnectedRx.value ? 160.h : 220.h; + + return RepaintBoundary( + // 添加重绘边界,优化动画性能 + child: AnimatedContainer( + duration: const Duration(milliseconds: 500), + curve: Curves.easeInOut, + height: imageHeight, + child: PageView( + children: [ + Center( + child: ClipRRect( + borderRadius: BorderRadius.circular(16.r), + child: Image.asset( + isDarkMode + ? 'assets/images/headphone_new3.png' + : 'assets/images/headphone_new4.png', + height: imageHeight, + fit: BoxFit.contain, + ), ), ), - ), - ], + ], + ), ), ); } - - // 带动画的设备状态卡片 - 实现平滑的高度变化过渡 Widget _buildAnimatedDeviceStatusCard(bool isDarkMode) { return Obx(() {