From ac975f8a6fa50546523dce2e99a8f0086e11160a Mon Sep 17 00:00:00 2001 From: tanlongsheng <252620078@qq.com> Date: Thu, 21 Aug 2025 21:58:32 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=96=B0=E6=89=8B=E6=8C=87?= =?UTF-8?q?=E5=BC=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/core/widgets/intro_overlay_builder.dart | 107 ++++++--- lib/modules/agent/views/agent_view.dart | 244 ++++++++++---------- lib/modules/home/views/home_view.dart | 8 +- 3 files changed, 192 insertions(+), 167 deletions(-) diff --git a/lib/core/widgets/intro_overlay_builder.dart b/lib/core/widgets/intro_overlay_builder.dart index a2c3eaa7a..13fbd0162 100644 --- a/lib/core/widgets/intro_overlay_builder.dart +++ b/lib/core/widgets/intro_overlay_builder.dart @@ -73,13 +73,16 @@ class IntroOverlayBuilder { bool alignment = true, Function? onNext, Function? onFinish, + Function? onTap, }) { - double height = - (params.offset?.dy ?? 0) - ScreenUtil().statusBarHeight - 20.w; + double dy = params.offset?.dy ?? 0; + double width = params.size.width; + double height = params.size.height; + double totalHeight = dy + height + 3 - ScreenUtil().statusBarHeight; double left = params.offset?.dx ?? 0; - double right = 1.sw - left - params.size.width; + double right = 1.sw - left - width; return SizedBox( - height: height, + height: totalHeight, child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -96,15 +99,15 @@ class IntroOverlayBuilder { ), Padding( padding: EdgeInsets.only( - left: alignment ? left : 12.w, - right: alignment ? 12.w : right, + left: alignment ? left - 3 : 12.w - 3, + right: alignment ? 12.w - 3 : right - 3, ), child: Column( crossAxisAlignment: alignment ? CrossAxisAlignment.start : CrossAxisAlignment.end, children: [ Padding( - padding: EdgeInsets.only(bottom: 10.w), + padding: const EdgeInsets.symmetric(horizontal: 3), child: Text( text, style: TextStyle( @@ -117,23 +120,51 @@ class IntroOverlayBuilder { Row( children: [ if (onNext != null) - _button( - buttonText, - () { - params.onNext!(); - onNext(); - }, + Padding( + padding: EdgeInsets.only(top: 10.w, left: 3, right: 3), + child: _button( + buttonText, + () { + params.onNext!(); + onNext(); + }, + ), ), if (onFinish != null) - _button( - buttonText, - () { - params.onFinish(); - onFinish(); - }, + Padding( + padding: EdgeInsets.only(top: 10.w, left: 3, right: 3), + child: _button( + buttonText, + () { + params.onFinish(); + onFinish(); + }, + ), ), ], ), + SizedBox(height: 20.w), + onTap != null + ? _AnimatedBorderButton( + onTap: () { + onTap(); + }, + isButton: false, + child: Padding( + padding: const EdgeInsetsGeometry.all(3), + child: SizedBox( + width: width, + height: height, + ), + ), + ) + : Padding( + padding: const EdgeInsetsGeometry.all(3), + child: SizedBox( + width: width, + height: height, + ), + ), ], ), ), @@ -162,8 +193,21 @@ class IntroOverlayBuilder { ), ) : _AnimatedBorderButton( - text: text, onTap: onTap, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 5.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20.r), + border: Border.all(color: Colors.transparent), + ), + child: Text( + text, + style: TextStyle( + fontSize: 14.sp, + color: Colors.white, + ), + ), + ), ); } } @@ -228,12 +272,14 @@ class _AnimatedLottieWidgetState extends State<_AnimatedLottieWidget> // 新增的带边框流动动画的按钮组件 class _AnimatedBorderButton extends StatefulWidget { - final String text; + final Widget child; + final bool isButton; final Function() onTap; const _AnimatedBorderButton({ - required this.text, + required this.child, required this.onTap, + this.isButton = true, }); @override @@ -276,22 +322,9 @@ class _AnimatedBorderButtonState extends State<_AnimatedBorderButton> return CustomPaint( painter: _FlowingBorderPainter( progress: _animation.value, - borderRadius: 20.r, - ), - child: Container( - padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 5.w), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20.r), - border: Border.all(color: Colors.transparent), - ), - child: Text( - widget.text, - style: TextStyle( - fontSize: 14.sp, - color: Colors.white, - ), - ), + borderRadius: widget.isButton ? 20.r : 0.r, ), + child: widget.child, ); }, ), diff --git a/lib/modules/agent/views/agent_view.dart b/lib/modules/agent/views/agent_view.dart index 419261a77..4681a6fba 100644 --- a/lib/modules/agent/views/agent_view.dart +++ b/lib/modules/agent/views/agent_view.dart @@ -742,151 +742,143 @@ class _AgentViewState extends State with WidgetsBindingObserver { SizedBox(width: 8.w), // 动态按钮区域:展开按钮 + 发送按钮 或 图片选择按钮 - Builder(builder: (context) { - StepWidgetParams? widgetParams; - return IntroStepBuilder( - group: 'ai', - order: 2, - onHighlightWidgetTap: () async { - await controller - .noviceGuideService.aiStepsList[ - controller.noviceGuideService.aiStep] - ['method'](); - widgetParams!.onNext!(); - controller.sendMessage(); - }, - getOverlayPosition: - IntroOverlayBuilder.overlayPosition, - overlayBuilder: (params) { - widgetParams = params; - return IntroOverlayBuilder.aiBuilder( - params, - '点击发送,${controller.noviceGuideService.aiStepsList[controller.noviceGuideService.aiStep]['send']}', - alignment: false, - ); - }, - builder: - (BuildContext context, GlobalKey key) => - Obx( - key: key, - () { - final hasText = - controller.hasTextInput.value; - final hasImage = - controller.isImageInputActive.value; - final shouldShowSend = hasText || hasImage; - final shouldShowExpand = - controller.shouldShowExpandButton.value; + IntroStepBuilder( + group: 'ai', + order: 2, + getOverlayPosition: + IntroOverlayBuilder.overlayPosition, + overlayBuilder: (params) { + return IntroOverlayBuilder.aiBuilder( + params, + '点击发送,${controller.noviceGuideService.aiStepsList[controller.noviceGuideService.aiStep]['send']}', + alignment: false, + onTap: () async { + await controller + .noviceGuideService.aiStepsList[ + controller.noviceGuideService + .aiStep]['method'](); + params.onNext!(); + controller.sendMessage(); + }, + ); + }, + builder: (BuildContext context, GlobalKey key) => + Obx( + key: key, + () { + final hasText = controller.hasTextInput.value; + final hasImage = + controller.isImageInputActive.value; + final shouldShowSend = hasText || hasImage; + final shouldShowExpand = + controller.shouldShowExpandButton.value; - if (shouldShowSend) { - // 显示发送按钮(可能还有展开按钮) - return Column( - children: [ - // 展开按钮(在发送按钮上方) - if (shouldShowExpand && hasText) - Padding( - padding: - EdgeInsets.only(bottom: 40.h), - child: GestureDetector( - onTap: () { - // 打开底部弹出编辑模式 + if (shouldShowSend) { + // 显示发送按钮(可能还有展开按钮) + return Column( + children: [ + // 展开按钮(在发送按钮上方) + if (shouldShowExpand && hasText) + Padding( + padding: + EdgeInsets.only(bottom: 40.h), + child: GestureDetector( + onTap: () { + // 打开底部弹出编辑模式 + controller.openFullScreenEdit(); + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: + Colors.transparent, + builder: (context) => + const FullScreenEditor(), + ).then((_) { + // 弹出页关闭时的回调 controller - .openFullScreenEdit(); - showModalBottomSheet( - context: context, - isScrollControlled: true, - backgroundColor: - Colors.transparent, - builder: (context) => - const FullScreenEditor(), - ).then((_) { - // 弹出页关闭时的回调 - controller - .closeFullScreenEdit(); - }); - }, - child: Container( - width: 32.w, - height: 32.w, - decoration: BoxDecoration( - color: isDarkMode - ? Colors.grey[700] - : Colors.grey[300], - borderRadius: - BorderRadius.circular( - 16.w), - ), - child: Icon( - Icons.expand_less, - color: isDarkMode - ? Colors.grey[300] - : Colors.grey[700], - size: 20.sp, - ), + .closeFullScreenEdit(); + }); + }, + child: Container( + width: 32.w, + height: 32.w, + decoration: BoxDecoration( + color: isDarkMode + ? Colors.grey[700] + : Colors.grey[300], + borderRadius: + BorderRadius.circular( + 16.w), + ), + child: Icon( + Icons.expand_less, + color: isDarkMode + ? Colors.grey[300] + : Colors.grey[700], + size: 20.sp, ), - ), - ), - // 发送按钮 - GestureDetector( - onTap: () => - controller.sendMessage(), - child: Container( - width: 44.w, - height: 44.w, - margin: EdgeInsets.symmetric( - vertical: 2.w), - decoration: BoxDecoration( - color: primaryColor, - borderRadius: - BorderRadius.circular(22.w), - ), - child: Icon( - Icons.send, - color: Colors.white, - size: 22.sp, ), ), ), - ], - ); - } else { - // 显示'+'选择按钮 - return Obx(() { - final isExpanded = controller - .isPlusOptionsExpanded.value; - return GestureDetector( - onTap: () { - controller.togglePlusOptions(); - }, + // 发送按钮 + GestureDetector( + onTap: () => controller.sendMessage(), child: Container( width: 44.w, height: 44.w, margin: EdgeInsets.symmetric( vertical: 2.w), decoration: BoxDecoration( - color: isDarkMode - ? Colors.grey[800] - : Colors.grey[200], + color: primaryColor, borderRadius: BorderRadius.circular(22.w), ), child: Icon( - isExpanded - ? Icons.close - : Icons.add, - color: isDarkMode - ? Colors.grey[300] - : Colors.grey[700], + Icons.send, + color: Colors.white, size: 22.sp, ), ), - ); - }); - } - }, - ), - ); - }), + ), + ], + ); + } else { + // 显示'+'选择按钮 + return Obx(() { + final isExpanded = controller + .isPlusOptionsExpanded.value; + return GestureDetector( + onTap: () { + controller.togglePlusOptions(); + }, + child: Container( + width: 44.w, + height: 44.w, + margin: EdgeInsets.symmetric( + vertical: 2.w), + decoration: BoxDecoration( + color: isDarkMode + ? Colors.grey[800] + : Colors.grey[200], + borderRadius: + BorderRadius.circular(22.w), + ), + child: Icon( + isExpanded + ? Icons.close + : Icons.add, + color: isDarkMode + ? Colors.grey[300] + : Colors.grey[700], + size: 22.sp, + ), + ), + ); + }); + } + }, + ), + ), ], ), diff --git a/lib/modules/home/views/home_view.dart b/lib/modules/home/views/home_view.dart index 7ff7eb91a..df4d421ca 100644 --- a/lib/modules/home/views/home_view.dart +++ b/lib/modules/home/views/home_view.dart @@ -740,15 +740,15 @@ class HomeView extends GetView { child: IntroStepBuilder( group: 'home', order: 3, - onHighlightWidgetTap: () { - Intro.of(Get.context!).dispose(); - controller.exploreAIFeatures(); - }, getOverlayPosition: IntroOverlayBuilder.overlayPosition, overlayBuilder: (params) { return IntroOverlayBuilder.aiBuilder( params, '太棒了!你已成功唤醒小言,接下来试试让它帮你做件事吧', + onTap: () { + params.onFinish(); + controller.exploreAIFeatures(); + }, ); }, builder: (BuildContext context, GlobalKey key) => SizedBox(