From cd94daef52ba6ffc4d23669ae21a19ca53ef1898 Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Mon, 2 Feb 2026 10:33:04 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=9C=A8=E5=A4=9A=E4=B8=AA=E8=A7=86?= =?UTF-8?q?=E5=9B=BE=E7=9A=84Scaffold=20body=E4=B8=AD=E5=8C=85=E8=A3=B9Saf?= =?UTF-8?q?eArea=E9=98=B2=E6=AD=A2=E5=86=85=E5=AE=B9=E8=A2=AB=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=A0=8F=E9=81=AE=E6=8C=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为多个视图的Scaffold body添加SafeArea包装,设置top: false以避免内容被系统状态栏遮挡,确保UI在不同设备上正确显示 --- lib/modules/agent/views/agent_view.dart | 1477 +++++++++-------- .../eq_settings/views/eq_settings_view.dart | 5 +- .../widgets/select_equalizer_widget.dart | 5 +- .../meeting/views/meeting_record_view.dart | 17 +- lib/modules/meeting/views/meeting_view.dart | 75 +- .../views/mine/meeting_member_view.dart | 5 +- .../mine/meeting_transcription_view.dart | 5 +- .../meeting/views/template/template_view.dart | 5 +- .../views/translation_detail_view.dart | 35 +- .../views/translation_history_view.dart | 90 +- .../views/translation_list_view.dart | 9 +- .../translation/views/translation_view.dart | 120 +- 12 files changed, 953 insertions(+), 895 deletions(-) diff --git a/lib/modules/agent/views/agent_view.dart b/lib/modules/agent/views/agent_view.dart index 8a3674b0c..8db6251da 100644 --- a/lib/modules/agent/views/agent_view.dart +++ b/lib/modules/agent/views/agent_view.dart @@ -376,103 +376,130 @@ class _AgentViewState extends State with WidgetsBindingObserver { ), ], ), - body: Stack( - children: [ - IntroStepBuilder( - group: 'ai', - order: 3, - getOverlayPosition: IntroOverlayBuilder.overlayPosition, - overlayBuilder: (params) { - return Obx( - () => IntroOverlayBuilder.homeBuilder( - params, - false, - title: controller.newAIReplyCompleted.value - ? 'aiReplyCompleted'.tr - : 'aiThinking'.tr, - onNext: controller.newAIReplyCompleted.value ? () {} : null, - ), - ); - }, - builder: (BuildContext context, GlobalKey key) => SizedBox( - key: key, + body: SafeArea( + top: false, + child: Stack( + children: [ + IntroStepBuilder( + group: 'ai', + order: 3, + getOverlayPosition: IntroOverlayBuilder.overlayPosition, + overlayBuilder: (params) { + return Obx( + () => IntroOverlayBuilder.homeBuilder( + params, + false, + title: controller.newAIReplyCompleted.value + ? 'aiReplyCompleted'.tr + : 'aiThinking'.tr, + onNext: controller.newAIReplyCompleted.value ? () {} : null, + ), + ); + }, + builder: (BuildContext context, GlobalKey key) => SizedBox( + key: key, + ), ), - ), - // 主要聊天界面 - Column( - children: [ - // 聊天内容 - Expanded( - child: GestureDetector( - onTap: () { - // 点击聊天区域时,收起键盘并切换工具显示状态 - FocusScope.of(context).unfocus(); - if (controller.isPlusOptionsExpanded.value) { - controller.collapsePlusOptions(); - } - }, - child: Obx(() { - return Align( - alignment: Alignment.topCenter, - child: ListView.builder( - controller: controller.scrollController, - shrinkWrap: true, - reverse: true, - padding: EdgeInsets.symmetric( - vertical: 16.h, horizontal: 16.w), - itemCount: controller.messages.length + - (controller.hasMoreMessages.value ? 1 : 0), - itemBuilder: (context, index) { - // 如果是最后一项且有更多消息,显示加载指示器 - if (index == controller.messages.length && - controller.hasMoreMessages.value) { - return _buildLoadMoreIndicator(); - } + // 主要聊天界面 + Column( + children: [ + // 聊天内容 + Expanded( + child: GestureDetector( + onTap: () { + // 点击聊天区域时,收起键盘并切换工具显示状态 + FocusScope.of(context).unfocus(); + if (controller.isPlusOptionsExpanded.value) { + controller.collapsePlusOptions(); + } + }, + child: Obx(() { + return Align( + alignment: Alignment.topCenter, + child: ListView.builder( + controller: controller.scrollController, + shrinkWrap: true, + reverse: true, + padding: EdgeInsets.symmetric( + vertical: 16.h, horizontal: 16.w), + itemCount: controller.messages.length + + (controller.hasMoreMessages.value ? 1 : 0), + itemBuilder: (context, index) { + // 如果是最后一项且有更多消息,显示加载指示器 + if (index == controller.messages.length && + controller.hasMoreMessages.value) { + return _buildLoadMoreIndicator(); + } - final message = controller - .messages[controller.messages.length - 1 - index]; - return index == 0 - ? IntroStepBuilder( - group: 'ai', - order: 4, - getOverlayPosition: - IntroOverlayBuilder.overlayPosition, - overlayBuilder: (params) { - return IntroOverlayBuilder.aiBuilder( - params, - '${controller.noviceGuideService.aiStepsList[controller.noviceGuideService.aiStep]['endKey']}' - .tr, - onFinish: () async { - if (controller - .noviceGuideService.aiStep < - 5) { - await Future.delayed(const Duration( - milliseconds: 300)); - controller - .noviceGuideService.aiStep++; - Intro.of(Get.context!) - .start(group: 'ai', reset: true); - } - }, - onTap: () async { - params.onFinish(); - if (controller - .noviceGuideService.aiStep < - 5) { - await Future.delayed(const Duration( - milliseconds: 300)); - controller - .noviceGuideService.aiStep++; - Intro.of(Get.context!) - .start(group: 'ai', reset: true); - } - }, - ); - }, - builder: - (BuildContext context, GlobalKey key) => - Padding( - key: key, + final message = controller.messages[ + controller.messages.length - 1 - index]; + return index == 0 + ? IntroStepBuilder( + group: 'ai', + order: 4, + getOverlayPosition: + IntroOverlayBuilder.overlayPosition, + overlayBuilder: (params) { + return IntroOverlayBuilder.aiBuilder( + params, + '${controller.noviceGuideService.aiStepsList[controller.noviceGuideService.aiStep]['endKey']}' + .tr, + onFinish: () async { + if (controller + .noviceGuideService.aiStep < + 5) { + await Future.delayed(const Duration( + milliseconds: 300)); + controller + .noviceGuideService.aiStep++; + Intro.of(Get.context!).start( + group: 'ai', reset: true); + } + }, + onTap: () async { + params.onFinish(); + if (controller + .noviceGuideService.aiStep < + 5) { + await Future.delayed(const Duration( + milliseconds: 300)); + controller + .noviceGuideService.aiStep++; + Intro.of(Get.context!).start( + group: 'ai', reset: true); + } + }, + ); + }, + builder: + (BuildContext context, GlobalKey key) => + Padding( + key: key, + padding: EdgeInsets.only(bottom: 8.h), + child: GestureDetector( + onLongPressStart: + (LongPressStartDetails details) { + messageActionController + .onLongPressMessage(context, + isDarkMode, details, message); + }, + child: MessageBubble( + sessionid: message.sessionid, + isUser: message.isUser, + message: message.text, + timestamp: message.timestamp, + isRecognizing: message.isRecognizing, + hasImage: message.hasImage, + imagePath: message.imagePath, + meta: message.meta, + functionCalls: message.functionCalls, + isToolCallsExpanded: + message.isToolCallsExpanded, + ), + ), + ), + ) + : Padding( padding: EdgeInsets.only(bottom: 8.h), child: GestureDetector( onLongPressStart: @@ -495,707 +522,699 @@ class _AgentViewState extends State with WidgetsBindingObserver { message.isToolCallsExpanded, ), ), - ), - ) - : Padding( - padding: EdgeInsets.only(bottom: 8.h), - child: GestureDetector( - onLongPressStart: - (LongPressStartDetails details) { - messageActionController - .onLongPressMessage(context, - isDarkMode, details, message); - }, - child: MessageBubble( - sessionid: message.sessionid, - isUser: message.isUser, - message: message.text, - timestamp: message.timestamp, - isRecognizing: message.isRecognizing, - hasImage: message.hasImage, - imagePath: message.imagePath, - meta: message.meta, - functionCalls: message.functionCalls, - isToolCallsExpanded: - message.isToolCallsExpanded, - ), - ), - ); - }, - ), - ); - }), + ); + }, + ), + ); + }), + ), ), - ), - // 输入区域 - Container( - padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h), - decoration: BoxDecoration( - color: backgroundColor, - boxShadow: [ - BoxShadow( - color: Colors.black.withValues(alpha: 0.06), - blurRadius: 8.w, - offset: const Offset(0, -1), - ), - ], - border: Border( - top: BorderSide( - color: Colors.grey.withValues(alpha: 0.15), - width: 1.w, + // 输入区域 + Container( + padding: + EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h), + decoration: BoxDecoration( + color: backgroundColor, + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.06), + blurRadius: 8.w, + offset: const Offset(0, -1), + ), + ], + border: Border( + top: BorderSide( + color: Colors.grey.withValues(alpha: 0.15), + width: 1.w, + ), ), ), - ), - child: Column( - children: [ - // 图片预览区域 - 仅在图片输入模式下显示 - Obx( - () { - if (controller.isImageInputActive.value && - controller.selectedImagePath.value != null) { - return Column( - children: [ - // 图片预览和关闭按钮 - Stack( - children: [ - ClipRRect( - borderRadius: BorderRadius.circular(12.w), - child: Image.file( - File(controller.selectedImagePath.value!), - height: 150.h, - width: double.infinity, - fit: BoxFit.cover, + child: Column( + children: [ + // 图片预览区域 - 仅在图片输入模式下显示 + Obx( + () { + if (controller.isImageInputActive.value && + controller.selectedImagePath.value != null) { + return Column( + children: [ + // 图片预览和关闭按钮 + Stack( + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(12.w), + child: Image.file( + File(controller + .selectedImagePath.value!), + height: 150.h, + width: double.infinity, + fit: BoxFit.cover, + ), ), - ), - Positioned( - top: 8.h, - right: 8.w, - child: GestureDetector( - onTap: () => controller.clearImageInput(), - child: Container( - padding: EdgeInsets.all(4.w), - decoration: BoxDecoration( - color: Colors.black - .withValues(alpha: 0.6), - shape: BoxShape.circle, - ), - child: Icon( - Icons.close, - color: Colors.white, - size: 16.sp, + Positioned( + top: 8.h, + right: 8.w, + child: GestureDetector( + onTap: () => + controller.clearImageInput(), + child: Container( + padding: EdgeInsets.all(4.w), + decoration: BoxDecoration( + color: Colors.black + .withValues(alpha: 0.6), + shape: BoxShape.circle, + ), + child: Icon( + Icons.close, + color: Colors.white, + size: 16.sp, + ), ), ), ), - ), - ], - ), - - // 预设提示选项 - SizedBox(height: 12.h), - SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Row( - children: [ - _buildPromptChip( - context: context, - label: - 'summarizeImageContent'.tr, //总结图片内容 - onTap: () => controller.summarizeImage(), - ), - SizedBox(width: 8.w), - _buildPromptChip( - context: context, - label: 'extractImageText'.tr, //抽取图像文字 - onTap: () => - controller.extractTextFromImage(), - ), - SizedBox(width: 8.w), - _buildPromptChip( - context: context, - label: 'translateImageText'.tr, //翻译图像文字 - onTap: () => - controller.translateImageText(), - ), ], ), - ), - SizedBox(height: 12.h), - ], - ); - } else { - // 文本输入模式下,且输入框为空 - return Column( - children: [ - SingleChildScrollView( + + // 预设提示选项 + SizedBox(height: 12.h), + SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( children: [ _buildPromptChip( - context: context, - label: 'presetMusic'.tr, // 来点音乐 - onTap: () => controller - .preSetPromptAction('Music')), - SizedBox(width: 8.w), - _buildPromptChip( - context: context, - label: 'presetNavigation'.tr, // 导航 - onTap: () => - controller.preSetPromptAction( - 'Navigation')), - SizedBox(width: 8.w), - _buildPromptChip( - context: context, - label: 'presetWeather'.tr, // 天气 - onTap: () => controller - .preSetPromptAction('Weather')), + context: context, + label: + 'summarizeImageContent'.tr, //总结图片内容 + onTap: () => + controller.summarizeImage(), + ), SizedBox(width: 8.w), _buildPromptChip( - context: context, - label: 'presetNews'.tr, // 新闻 - onTap: () => controller - .preSetPromptAction('News')), + context: context, + label: 'extractImageText'.tr, //抽取图像文字 + onTap: () => + controller.extractTextFromImage(), + ), SizedBox(width: 8.w), _buildPromptChip( - context: context, - label: 'presetFood'.tr, // 美食 - onTap: () => controller - .preSetPromptAction('Food')), + context: context, + label: 'translateImageText'.tr, //翻译图像文字 + onTap: () => + controller.translateImageText(), + ), ], - )), - SizedBox(height: 12.h), - ], - ); - } - }, - ), - - // 输入控件区域 - 包含输入行和展开的选项 - Column( - children: [ - Row( - crossAxisAlignment: - CrossAxisAlignment.end, // 所有元素底部对齐 - children: [ - // 键盘/语音切换按钮 - Obx(() { - final isTextMode = - controller.isTextInputMode.value; - return GestureDetector( - onTap: () { - controller.toggleInputMode(); - // 切换模式时,确保焦点正确 - if (!isTextMode) { - // 切换到语音模式时,请求焦点 - Future.delayed(Duration.zero, () { - _textFocusNode.requestFocus(); - }); - } - }, - 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), - ), - child: Icon( - isTextMode - ? Icons.mic_none - : Icons.keyboard, - color: isDarkMode - ? Colors.grey[300] - : Colors.grey[700], - size: 22.sp, ), ), - ); - }), - - SizedBox(width: 8.w), + SizedBox(height: 12.h), + ], + ); + } else { + // 文本输入模式下,且输入框为空 + return Column( + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + _buildPromptChip( + context: context, + label: 'presetMusic'.tr, // 来点音乐 + onTap: () => controller + .preSetPromptAction('Music')), + SizedBox(width: 8.w), + _buildPromptChip( + context: context, + label: 'presetNavigation'.tr, // 导航 + onTap: () => + controller.preSetPromptAction( + 'Navigation')), + SizedBox(width: 8.w), + _buildPromptChip( + context: context, + label: 'presetWeather'.tr, // 天气 + onTap: () => controller + .preSetPromptAction('Weather')), + SizedBox(width: 8.w), + _buildPromptChip( + context: context, + label: 'presetNews'.tr, // 新闻 + onTap: () => controller + .preSetPromptAction('News')), + SizedBox(width: 8.w), + _buildPromptChip( + context: context, + label: 'presetFood'.tr, // 美食 + onTap: () => controller + .preSetPromptAction('Food')), + ], + )), + SizedBox(height: 12.h), + ], + ); + } + }, + ), - // 文本输入框或语音波形图 - Expanded( - child: Obx(() { + // 输入控件区域 - 包含输入行和展开的选项 + Column( + children: [ + Row( + crossAxisAlignment: + CrossAxisAlignment.end, // 所有元素底部对齐 + children: [ + // 键盘/语音切换按钮 + Obx(() { final isTextMode = controller.isTextInputMode.value; + return GestureDetector( + onTap: () { + controller.toggleInputMode(); + // 切换模式时,确保焦点正确 + if (!isTextMode) { + // 切换到语音模式时,请求焦点 + Future.delayed(Duration.zero, () { + _textFocusNode.requestFocus(); + }); + } + }, + 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), + ), + child: Icon( + isTextMode + ? Icons.mic_none + : Icons.keyboard, + color: isDarkMode + ? Colors.grey[300] + : Colors.grey[700], + size: 22.sp, + ), + ), + ); + }), - if (isTextMode) { - // 文本输入模式 - 限制最大高度并只向上扩展 - return IntroStepBuilder( - group: 'ai', - order: 1, - getOverlayPosition: - IntroOverlayBuilder.overlayPosition, - overlayBuilder: (params) { - return IntroOverlayBuilder.aiBuilder( - params, - '${controller.noviceGuideService.aiStepsList[controller.noviceGuideService.aiStep]['startKey']}' - .tr, - buttonText: 'confirmInput'.tr, - onNext: () { - controller.textController.text = - '${controller.noviceGuideService.aiStepsList[controller.noviceGuideService.aiStep]['inputKey']}' - .tr; - }, - onTap: () { - controller.textController.text = - '${controller.noviceGuideService.aiStepsList[controller.noviceGuideService.aiStep]['inputKey']}' - .tr; - params.onNext!(); - }, - ); - }, - onWidgetLoad: () { - controller.noviceGuideService - .startAIGuide(); - }, - builder: - (BuildContext context, GlobalKey key) => - Container( - key: key, - constraints: BoxConstraints( - minHeight: 48.w, - ), - padding: EdgeInsets.symmetric( - horizontal: 16.w, - vertical: 5.w, - ), - alignment: Alignment.center, - decoration: BoxDecoration( - color: isDarkMode - ? Colors.grey[800] - : Colors.grey[200], - borderRadius: - BorderRadius.circular(22.w), - border: Border.all( - color: isDarkMode - ? Colors.grey[800]! - : Colors.grey - .withValues(alpha: 0.1), - width: 1.w, - ), - ), - child: Obx(() { - // 图片模式下使用更高的输入框 - final isImageActive = - controller.isImageInputActive.value; + SizedBox(width: 8.w), - return TextField( - focusNode: _textFocusNode, // 绑定焦点节点 - controller: controller.textController, - maxLines: isImageActive - ? 3 - : 5, // 设置合理的最大行数 - minLines: isImageActive ? 2 : 1, - keyboardType: - TextInputType.multiline, // 启用多行键盘 - textInputAction: - TextInputAction.newline, // 支持回车换行 + // 文本输入框或语音波形图 + Expanded( + child: Obx(() { + final isTextMode = + controller.isTextInputMode.value; + + if (isTextMode) { + // 文本输入模式 - 限制最大高度并只向上扩展 + return IntroStepBuilder( + group: 'ai', + order: 1, + getOverlayPosition: + IntroOverlayBuilder.overlayPosition, + overlayBuilder: (params) { + return IntroOverlayBuilder.aiBuilder( + params, + '${controller.noviceGuideService.aiStepsList[controller.noviceGuideService.aiStep]['startKey']}' + .tr, + buttonText: 'confirmInput'.tr, + onNext: () { + controller.textController.text = + '${controller.noviceGuideService.aiStepsList[controller.noviceGuideService.aiStep]['inputKey']}' + .tr; + }, onTap: () { - // 当点击输入框时,如果'+'选项已展开,则收缩 - if (controller - .isPlusOptionsExpanded.value) { - controller.collapsePlusOptions(); - } + controller.textController.text = + '${controller.noviceGuideService.aiStepsList[controller.noviceGuideService.aiStep]['inputKey']}' + .tr; + params.onNext!(); }, - style: TextStyle( - fontSize: 15.sp, + ); + }, + onWidgetLoad: () { + controller.noviceGuideService + .startAIGuide(); + }, + builder: (BuildContext context, + GlobalKey key) => + Container( + key: key, + constraints: BoxConstraints( + minHeight: 48.w, + ), + padding: EdgeInsets.symmetric( + horizontal: 16.w, + vertical: 5.w, + ), + alignment: Alignment.center, + decoration: BoxDecoration( + color: isDarkMode + ? Colors.grey[800] + : Colors.grey[200], + borderRadius: + BorderRadius.circular(22.w), + border: Border.all( color: isDarkMode - ? Colors.white - : Colors.grey[800], + ? Colors.grey[800]! + : Colors.grey + .withValues(alpha: 0.1), + width: 1.w, ), - decoration: InputDecoration( - hintText: isImageActive - ? 'addQuestionAboutImage' - .tr // 添加对图片的问题或描述... - : 'inputMessage'.tr, // 输入消息... - hintStyle: TextStyle( - color: Colors.grey[500], + ), + child: Obx(() { + // 图片模式下使用更高的输入框 + final isImageActive = controller + .isImageInputActive.value; + + return TextField( + focusNode: _textFocusNode, // 绑定焦点节点 + controller: + controller.textController, + maxLines: isImageActive + ? 3 + : 5, // 设置合理的最大行数 + minLines: isImageActive ? 2 : 1, + keyboardType: TextInputType + .multiline, // 启用多行键盘 + textInputAction: TextInputAction + .newline, // 支持回车换行 + onTap: () { + // 当点击输入框时,如果'+'选项已展开,则收缩 + if (controller + .isPlusOptionsExpanded + .value) { + controller + .collapsePlusOptions(); + } + }, + style: TextStyle( fontSize: 15.sp, + color: isDarkMode + ? Colors.white + : Colors.grey[800], ), - filled: false, - isDense: true, - border: InputBorder.none, - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: isDarkMode - ? Colors.grey[800]! - : Colors.grey[200]!, - width: 1.w, + decoration: InputDecoration( + hintText: isImageActive + ? 'addQuestionAboutImage' + .tr // 添加对图片的问题或描述... + : 'inputMessage' + .tr, // 输入消息... + hintStyle: TextStyle( + color: Colors.grey[500], + fontSize: 15.sp, ), + filled: false, + isDense: true, + border: InputBorder.none, + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: isDarkMode + ? Colors.grey[800]! + : Colors.grey[200]!, + width: 1.w, + ), + ), + contentPadding: EdgeInsets.zero, ), - contentPadding: EdgeInsets.zero, - ), - onSubmitted: (_) => - controller.sendMessage(), - ); - }), - ), - ); - } else { - // 语音输入模式 - 按住说话模式 - return Listener( - onPointerDown: (_) { - controller.startPushToTalk(); - }, - onPointerUp: (_) { - controller.endPushToTalk(); - }, - onPointerCancel: (_) { - controller.endPushToTalk(); - }, - // onLongPressStart: (_) { - // // 开始按住说话 - // controller.startPushToTalk(); - // }, - // onLongPressEnd: (_) { - // // 结束按住说话 - // controller.endPushToTalk(); - // }, - // onLongPressCancel: () { - // // 取消按住说话 - // controller.endPushToTalk(); - // }, - child: Obx(() { - final isPushToTalkActive = - controller.isPushToTalkActive.value; + onSubmitted: (_) => + controller.sendMessage(), + ); + }), + ), + ); + } else { + // 语音输入模式 - 按住说话模式 + return Listener( + onPointerDown: (_) { + controller.startPushToTalk(); + }, + onPointerUp: (_) { + controller.endPushToTalk(); + }, + onPointerCancel: (_) { + controller.endPushToTalk(); + }, + // onLongPressStart: (_) { + // // 开始按住说话 + // controller.startPushToTalk(); + // }, + // onLongPressEnd: (_) { + // // 结束按住说话 + // controller.endPushToTalk(); + // }, + // onLongPressCancel: () { + // // 取消按住说话 + // controller.endPushToTalk(); + // }, + child: Obx(() { + final isPushToTalkActive = + controller.isPushToTalkActive.value; - return Container( - height: 48.w, - padding: EdgeInsets.symmetric( - horizontal: 16.w), - decoration: BoxDecoration( - color: isPushToTalkActive - ? (isDarkMode - ? Colors.blue[900] - : Colors.blue[100]) - : (isDarkMode - ? Colors.grey[800] - : const Color.fromARGB( - 255, 255, 255, 255)), - borderRadius: - BorderRadius.circular(22.w), - boxShadow: [ - BoxShadow( - color: Colors.black - .withValues(alpha: 0.2), - spreadRadius: 1, - blurRadius: 2, - offset: const Offset(0, 1), - ), - ], - // border: Border.all( - // color: isPushToTalkActive - // ? Colors.blue - // : (isDarkMode - // ? Colors.grey[800]! - // : const Color.fromARGB( - // 255, 255, 255, 255) - // .withOpacity(0.1)), - // width: - // isPushToTalkActive ? 2.w : 1.w, - // ), - ), - child: Row( - children: [ - // 语音波形图 - 只在按住时显示 - if (isPushToTalkActive) ...[ - const AgentSoundBarsWidget(), - //const Spacer(), + return Container( + height: 48.w, + padding: EdgeInsets.symmetric( + horizontal: 16.w), + decoration: BoxDecoration( + color: isPushToTalkActive + ? (isDarkMode + ? Colors.blue[900] + : Colors.blue[100]) + : (isDarkMode + ? Colors.grey[800] + : const Color.fromARGB( + 255, 255, 255, 255)), + borderRadius: + BorderRadius.circular(22.w), + boxShadow: [ + BoxShadow( + color: Colors.black + .withValues(alpha: 0.2), + spreadRadius: 1, + blurRadius: 2, + offset: const Offset(0, 1), + ), ], + // border: Border.all( + // color: isPushToTalkActive + // ? Colors.blue + // : (isDarkMode + // ? Colors.grey[800]! + // : const Color.fromARGB( + // 255, 255, 255, 255) + // .withOpacity(0.1)), + // width: + // isPushToTalkActive ? 2.w : 1.w, + // ), + ), + child: Row( + children: [ + // 语音波形图 - 只在按住时显示 + if (isPushToTalkActive) ...[ + const AgentSoundBarsWidget(), + //const Spacer(), + ], - // 状态文字和图标 - Expanded( - child: Row( - mainAxisAlignment: - isPushToTalkActive - ? MainAxisAlignment - .center - : MainAxisAlignment - .center, - children: [ - Icon( - isPushToTalkActive - ? Icons.mic - : Icons.mic_none, - size: 16.sp, - color: isPushToTalkActive - ? Colors.blue - : Colors.grey[500], - ), - const SizedBox(width: 6), - Text( - isPushToTalkActive - ? 'recording' - .tr // 正在录音... - : 'holdToSpeak' - .tr, // 按住说话 - style: TextStyle( - fontSize: 14, - fontWeight: - FontWeight.w500, + // 状态文字和图标 + Expanded( + child: Row( + mainAxisAlignment: + isPushToTalkActive + ? MainAxisAlignment + .center + : MainAxisAlignment + .center, + children: [ + Icon( + isPushToTalkActive + ? Icons.mic + : Icons.mic_none, + size: 16.sp, color: isPushToTalkActive ? Colors.blue - : Colors.grey[600], + : Colors.grey[500], ), - ), - ], + const SizedBox(width: 6), + Text( + isPushToTalkActive + ? 'recording' + .tr // 正在录音... + : 'holdToSpeak' + .tr, // 按住说话 + style: TextStyle( + fontSize: 14, + fontWeight: + FontWeight.w500, + color: + isPushToTalkActive + ? Colors.blue + : Colors + .grey[600], + ), + ), + ], + ), ), - ), - ], - ), - ); - }), - ); - } - }), - ), + ], + ), + ); + }), + ); + } + }), + ), - SizedBox(width: 8.w), + SizedBox(width: 8.w), - // 动态按钮区域:展开按钮 + 发送按钮 或 图片选择按钮 - IntroStepBuilder( - group: 'ai', - order: 2, - getOverlayPosition: - IntroOverlayBuilder.overlayPosition, - overlayBuilder: (params) { - return IntroOverlayBuilder.aiBuilder( - params, - '${'guideClickSendPrefix'.tr}${'${controller.noviceGuideService.aiStepsList[controller.noviceGuideService.aiStep]['sendKey']}'.tr}', - 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; + // 动态按钮区域:展开按钮 + 发送按钮 或 图片选择按钮 + IntroStepBuilder( + group: 'ai', + order: 2, + getOverlayPosition: + IntroOverlayBuilder.overlayPosition, + overlayBuilder: (params) { + return IntroOverlayBuilder.aiBuilder( + params, + '${'guideClickSendPrefix'.tr}${'${controller.noviceGuideService.aiStepsList[controller.noviceGuideService.aiStep]['sendKey']}'.tr}', + 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: () { - // 打开底部弹出编辑模式 - controller.openFullScreenEdit(); - showModalBottomSheet( - context: context, - isScrollControlled: true, - backgroundColor: - Colors.transparent, - builder: (context) => - const FullScreenEditor(), - ).then((_) { - // 弹出页关闭时的回调 + if (shouldShowSend) { + // 显示发送按钮(可能还有展开按钮) + return Column( + children: [ + // 展开按钮(在发送按钮上方) + if (shouldShowExpand && hasText) + Padding( + padding: + EdgeInsets.only(bottom: 40.h), + child: GestureDetector( + onTap: () { + // 打开底部弹出编辑模式 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, + .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, + ), ), ), ), + // 发送按钮 + 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, + ), + ), ), - // 发送按钮 - GestureDetector( - onTap: () => controller.sendMessage(), + ], + ); + } 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: primaryColor, + color: isDarkMode + ? Colors.grey[800] + : Colors.grey[200], borderRadius: BorderRadius.circular(22.w), ), child: Icon( - Icons.send, - color: Colors.white, + isExpanded + ? Icons.close + : Icons.add, + color: isDarkMode + ? Colors.grey[300] + : Colors.grey[700], 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, - ), - ), - ); - }); - } - }, + ); + }); + } + }, + ), ), - ), - ], - ), + ], + ), - // 展开的'+'选择选项 - Obx(() { - final isExpanded = - controller.isPlusOptionsExpanded.value; - return AnimatedContainer( - duration: const Duration(milliseconds: 300), - curve: Curves.easeInOut, - height: isExpanded ? 100.h : 0, // 调整高度以适应按钮尺寸 - child: isExpanded - ? LayoutBuilder( - // 添加LayoutBuilder获取实际约束 - builder: (context, constraints) { - return SingleChildScrollView( - // 确保内容可滚动 - scrollDirection: - Axis.horizontal, // 水平滚动 - child: Container( - margin: EdgeInsets.only(top: 16.h), - padding: EdgeInsets.symmetric( - horizontal: 16.w), - // 根据可用宽度调整容器宽度 - width: max(constraints.maxWidth, - 300.w), // 最小300宽 - child: Wrap( - // 使用Wrap替代Row,自动换行 - alignment: WrapAlignment.center, - spacing: 26.w, // 按钮水平间距 - runSpacing: 8.h, // 按钮垂直间距 - children: [ - // 相机按钮 - _buildPlusOptionButton( - context: context, - icon: Icons.camera_alt, - label: 'takePhoto'.tr, // 拍照 - onTap: () async { - //controller.collapsePlusOptions(); - await controller.takePhoto(); - }, - isDarkMode: isDarkMode, - ), - // 相册按钮 - _buildPlusOptionButton( - context: context, - icon: Icons.photo_library, - label: 'photoAlbum'.tr, // 相册 - onTap: () async { - //controller.collapsePlusOptions(); - await controller.pickImage(); - }, - isDarkMode: isDarkMode, - ), - // 文件按钮(预留位置) - // _buildPlusOptionButton( - // context: context, - // icon: Icons.folder, - // label: '文件', - // onTap: () { - // //controller.collapsePlusOptions(); - // // TODO: 实现文件选择功能 - // }, - // isDarkMode: isDarkMode, - // ), - // 通话按钮 - _buildPlusOptionButton( - context: context, - icon: Icons.phone, - label: 'makeCall'.tr, // 打电话 - onTap: () { - // 启动打电话模式 - controller.startPhoneCall(); - }, - isDarkMode: isDarkMode, - ), - ], + // 展开的'+'选择选项 + Obx(() { + final isExpanded = + controller.isPlusOptionsExpanded.value; + return AnimatedContainer( + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + height: isExpanded ? 100.h : 0, // 调整高度以适应按钮尺寸 + child: isExpanded + ? LayoutBuilder( + // 添加LayoutBuilder获取实际约束 + builder: (context, constraints) { + return SingleChildScrollView( + // 确保内容可滚动 + scrollDirection: + Axis.horizontal, // 水平滚动 + child: Container( + margin: EdgeInsets.only(top: 16.h), + padding: EdgeInsets.symmetric( + horizontal: 16.w), + // 根据可用宽度调整容器宽度 + width: max(constraints.maxWidth, + 300.w), // 最小300宽 + child: Wrap( + // 使用Wrap替代Row,自动换行 + alignment: WrapAlignment.center, + spacing: 26.w, // 按钮水平间距 + runSpacing: 8.h, // 按钮垂直间距 + children: [ + // 相机按钮 + _buildPlusOptionButton( + context: context, + icon: Icons.camera_alt, + label: 'takePhoto'.tr, // 拍照 + onTap: () async { + //controller.collapsePlusOptions(); + await controller + .takePhoto(); + }, + isDarkMode: isDarkMode, + ), + // 相册按钮 + _buildPlusOptionButton( + context: context, + icon: Icons.photo_library, + label: 'photoAlbum'.tr, // 相册 + onTap: () async { + //controller.collapsePlusOptions(); + await controller + .pickImage(); + }, + isDarkMode: isDarkMode, + ), + // 文件按钮(预留位置) + // _buildPlusOptionButton( + // context: context, + // icon: Icons.folder, + // label: '文件', + // onTap: () { + // //controller.collapsePlusOptions(); + // // TODO: 实现文件选择功能 + // }, + // isDarkMode: isDarkMode, + // ), + // 通话按钮 + _buildPlusOptionButton( + context: context, + icon: Icons.phone, + label: 'makeCall'.tr, // 打电话 + onTap: () { + // 启动打电话模式 + controller.startPhoneCall(); + }, + isDarkMode: isDarkMode, + ), + ], + ), ), - ), - ); - }, - ) - : const SizedBox.shrink(), - ); - }), - ], - ), - ], + ); + }, + ) + : const SizedBox.shrink(), + ); + }), + ], + ), + ], + ), ), - ), - ], - ), + ], + ), - // 打电话模式覆盖层 - Obx(() { - if (controller.isPhoneCallMode.value) { - return _buildPhoneCallOverlay(context, isDarkMode); - } - return const SizedBox.shrink(); - }), - ], + // 打电话模式覆盖层 + Obx(() { + if (controller.isPhoneCallMode.value) { + return _buildPhoneCallOverlay(context, isDarkMode); + } + return const SizedBox.shrink(); + }), + ], + ), ), ); } diff --git a/lib/modules/eq_settings/views/eq_settings_view.dart b/lib/modules/eq_settings/views/eq_settings_view.dart index 67f0403e9..87f3cdddd 100644 --- a/lib/modules/eq_settings/views/eq_settings_view.dart +++ b/lib/modules/eq_settings/views/eq_settings_view.dart @@ -14,7 +14,10 @@ class EqSettingsView extends GetView { return Scaffold( backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], appBar: _buildAppBar(isDarkMode), - body: _buildBody(isDarkMode), + body: SafeArea( + top: false, + child: _buildBody(isDarkMode), + ), ); } diff --git a/lib/modules/eq_settings/views/widgets/select_equalizer_widget.dart b/lib/modules/eq_settings/views/widgets/select_equalizer_widget.dart index ea04be1f5..60178212f 100644 --- a/lib/modules/eq_settings/views/widgets/select_equalizer_widget.dart +++ b/lib/modules/eq_settings/views/widgets/select_equalizer_widget.dart @@ -41,7 +41,10 @@ class _SelectEqualizerWidgetState extends State { return Scaffold( backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], appBar: _buildAppBar(isDarkMode), - body: _buildBody(isDarkMode), + body: SafeArea( + top: false, + child: _buildBody(isDarkMode), + ), ); } diff --git a/lib/modules/meeting/views/meeting_record_view.dart b/lib/modules/meeting/views/meeting_record_view.dart index eca269957..952b4e7bf 100644 --- a/lib/modules/meeting/views/meeting_record_view.dart +++ b/lib/modules/meeting/views/meeting_record_view.dart @@ -307,13 +307,16 @@ class MeetingRecordView extends GetView { }), ], ), - body: Column( - children: [ - // 简化为单一音频界面,移除不必要的TabBar - Expanded( - child: _buildAudioTab(context, isDarkMode), - ), - ], + body: SafeArea( + top: false, + child: Column( + children: [ + // 简化为单一音频界面,移除不必要的TabBar + Expanded( + child: _buildAudioTab(context, isDarkMode), + ), + ], + ), ), ), ); diff --git a/lib/modules/meeting/views/meeting_view.dart b/lib/modules/meeting/views/meeting_view.dart index 27cbdd32f..a1aae3d57 100644 --- a/lib/modules/meeting/views/meeting_view.dart +++ b/lib/modules/meeting/views/meeting_view.dart @@ -35,42 +35,45 @@ class MeetingView extends GetView { left: 0, right: 0, child: Obx( - () => BottomNavigationBar( - items: [ - BottomNavigationBarItem( - icon: Icon(Icons.folder_outlined), - activeIcon: Icon(Icons.folder), - label: 'files'.tr, // 对应中文:文件 - ), - BottomNavigationBarItem( - icon: SizedBox(), - label: '', - ), - BottomNavigationBarItem( - icon: Icon(Icons.person_outline), - activeIcon: Icon(Icons.person), - label: 'mine'.tr, // 对应中文:我的 - ), - ], - backgroundColor: - isDarkMode ? const Color(0xFF1A1A1A) : Colors.white, - currentIndex: controller.pageIndex.value, - unselectedItemColor: Colors.grey, - selectedItemColor: isDarkMode ? Colors.white : Colors.blue, - unselectedFontSize: 10.sp, - selectedFontSize: 10.sp, - onTap: (int index) { - if (index == 1 || index == controller.pageIndex.value) { - return; - } - if (index == 0) { - controller.pageIndex.value = 0; - controller.pageController.jumpToPage(0); - } else { - controller.pageIndex.value = 2; - controller.pageController.jumpToPage(1); - } - }, + () => SafeArea( + top: false, + child: BottomNavigationBar( + items: [ + BottomNavigationBarItem( + icon: Icon(Icons.folder_outlined), + activeIcon: Icon(Icons.folder), + label: 'files'.tr, // 对应中文:文件 + ), + BottomNavigationBarItem( + icon: SizedBox(), + label: '', + ), + BottomNavigationBarItem( + icon: Icon(Icons.person_outline), + activeIcon: Icon(Icons.person), + label: 'mine'.tr, // 对应中文:我的 + ), + ], + backgroundColor: + isDarkMode ? const Color(0xFF1A1A1A) : Colors.white, + currentIndex: controller.pageIndex.value, + unselectedItemColor: Colors.grey, + selectedItemColor: isDarkMode ? Colors.white : Colors.blue, + unselectedFontSize: 10.sp, + selectedFontSize: 10.sp, + onTap: (int index) { + if (index == 1 || index == controller.pageIndex.value) { + return; + } + if (index == 0) { + controller.pageIndex.value = 0; + controller.pageController.jumpToPage(0); + } else { + controller.pageIndex.value = 2; + controller.pageController.jumpToPage(1); + } + }, + ), ), ), ), diff --git a/lib/modules/meeting/views/mine/meeting_member_view.dart b/lib/modules/meeting/views/mine/meeting_member_view.dart index 29875e100..bb9775c7d 100644 --- a/lib/modules/meeting/views/mine/meeting_member_view.dart +++ b/lib/modules/meeting/views/mine/meeting_member_view.dart @@ -24,7 +24,10 @@ class _MeetingMemberViewState extends State { return Scaffold( backgroundColor: Colors.black, appBar: _buildAppBar(), - body: _buildBody(), + body: SafeArea( + top: false, + child: _buildBody(), + ), ); } diff --git a/lib/modules/meeting/views/mine/meeting_transcription_view.dart b/lib/modules/meeting/views/mine/meeting_transcription_view.dart index fca4c5e50..048ab9d92 100644 --- a/lib/modules/meeting/views/mine/meeting_transcription_view.dart +++ b/lib/modules/meeting/views/mine/meeting_transcription_view.dart @@ -18,7 +18,10 @@ class MeetingTranscriptionView extends GetView { return Scaffold( backgroundColor: MeetingUIUtils.getBackgroundColor(isDarkMode), appBar: _buildAppBar(isDarkMode), - body: _buildBody(isDarkMode), + body: SafeArea( + top: false, + child: _buildBody(isDarkMode), + ), ); } diff --git a/lib/modules/meeting/views/template/template_view.dart b/lib/modules/meeting/views/template/template_view.dart index 84fd2fb2e..3efcd1716 100644 --- a/lib/modules/meeting/views/template/template_view.dart +++ b/lib/modules/meeting/views/template/template_view.dart @@ -104,7 +104,10 @@ class _TemplateViewState extends State { return Scaffold( backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], appBar: _buildAppBar(isDarkMode), - body: _buildBody(isDarkMode), + body: SafeArea( + top: false, + child: _buildBody(isDarkMode), + ), ); } diff --git a/lib/modules/translation/views/translation_detail_view.dart b/lib/modules/translation/views/translation_detail_view.dart index 7a10c65da..6ad3db2ba 100644 --- a/lib/modules/translation/views/translation_detail_view.dart +++ b/lib/modules/translation/views/translation_detail_view.dart @@ -41,23 +41,26 @@ class TranslationDetailView extends GetView { backgroundColor: isDarkMode ? AppColors.darkBackground : Color(0xFFF5F5F8), appBar: _buildAppBar(isDarkMode), - body: Obx(() { - // 显示加载状态 - if (controller.isLoading.value) { - return Center( - child: CircularProgressIndicator( - color: isDarkMode ? AppColors.primary : Colors.blue, - ), - ); - } + body: SafeArea( + top: false, + child: Obx(() { + // 显示加载状态 + if (controller.isLoading.value) { + return Center( + child: CircularProgressIndicator( + color: isDarkMode ? AppColors.primary : Colors.blue, + ), + ); + } - return Column( - children: [ - _buildTabButtons(isDarkMode), - _buildContentArea(isDarkMode), - ], - ); - }), + return Column( + children: [ + _buildTabButtons(isDarkMode), + _buildContentArea(isDarkMode), + ], + ); + }), + ), ); } diff --git a/lib/modules/translation/views/translation_history_view.dart b/lib/modules/translation/views/translation_history_view.dart index 70a0c67fe..8fb2ededa 100644 --- a/lib/modules/translation/views/translation_history_view.dart +++ b/lib/modules/translation/views/translation_history_view.dart @@ -23,55 +23,59 @@ class TranslationHistoryView backgroundColor: isDarkMode ? AppColors.darkBackground : Color(0xFFF5F5F8), appBar: _buildAppBar(isDarkMode), - body: Obx(() { - if (!controller.hasHistory) { - return Center( - child: Text( - 'noTranslationHistory'.tr, - style: TextStyle( - fontSize: 16.sp, - color: isDarkMode ? Colors.grey[400] : Colors.grey, + body: SafeArea( + top: false, + child: Obx(() { + if (!controller.hasHistory) { + return Center( + child: Text( + 'noTranslationHistory'.tr, + style: TextStyle( + fontSize: 16.sp, + color: isDarkMode ? Colors.grey[400] : Colors.grey, + ), ), - ), - ); - } + ); + } - if (controller.isLoading.value) { - return Center( - child: CircularProgressIndicator( - color: isDarkMode ? AppColors.primary : Colors.blue, - ), - ); - } + if (controller.isLoading.value) { + return Center( + child: CircularProgressIndicator( + color: isDarkMode ? AppColors.primary : Colors.blue, + ), + ); + } - return ListView.builder( - padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h), - itemCount: controller.sortedDates.length, - itemBuilder: (context, index) { - final date = controller.sortedDates[index]; - final items = controller.groupedHistory.value[date]!; + return ListView.builder( + padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h), + itemCount: controller.sortedDates.length, + itemBuilder: (context, index) { + final date = controller.sortedDates[index]; + final items = controller.groupedHistory.value[date]!; - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.only(top: 24.h, bottom: 12.h, left: 12.w), - child: Text( - date, - style: TextStyle( - fontSize: 14.sp, - fontWeight: FontWeight.w600, - color: isDarkMode ? Colors.grey[400] : Colors.grey[600], - letterSpacing: 1.0, + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: + EdgeInsets.only(top: 24.h, bottom: 12.h, left: 12.w), + child: Text( + date, + style: TextStyle( + fontSize: 14.sp, + fontWeight: FontWeight.w600, + color: isDarkMode ? Colors.grey[400] : Colors.grey[600], + letterSpacing: 1.0, + ), ), ), - ), - _buildDateGroupContainer(items, isDarkMode), - ], - ); - }, - ); - }), + _buildDateGroupContainer(items, isDarkMode), + ], + ); + }, + ); + }), + ), ); } diff --git a/lib/modules/translation/views/translation_list_view.dart b/lib/modules/translation/views/translation_list_view.dart index d559a8d8e..4968bc573 100644 --- a/lib/modules/translation/views/translation_list_view.dart +++ b/lib/modules/translation/views/translation_list_view.dart @@ -19,7 +19,10 @@ class TranslationListView extends GetView { return Scaffold( backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], appBar: _buildAppBar(context, isDarkMode), - body: _buildAudioList(context, isDarkMode), + body: SafeArea( + top: false, + child: _buildAudioList(context, isDarkMode), + ), ); } @@ -216,7 +219,9 @@ class TranslationListView extends GetView { // 播放状态文本 Text( isCurrentFile - ? (isPlaying ? 'playing'.tr : 'paused'.tr) // 播放中... : 已暂停 + ? (isPlaying + ? 'playing'.tr + : 'paused'.tr) // 播放中... : 已暂停 : 'clickToPlay'.tr, // 点击播放 style: TextStyle( color: Colors.blue, diff --git a/lib/modules/translation/views/translation_view.dart b/lib/modules/translation/views/translation_view.dart index 75df6b81b..3f634311f 100644 --- a/lib/modules/translation/views/translation_view.dart +++ b/lib/modules/translation/views/translation_view.dart @@ -54,15 +54,18 @@ class TranslationView extends GetView { backgroundColor: isDarkMode ? AppColors.darkBackground : Colors.grey[50], appBar: _buildAppBar(isDarkMode), - body: Stack( - children: [ - _buildBody(isDarkMode), - // 可拖拽的悬浮按钮 - // DraggableFloatingButton( - // isDarkMode: isDarkMode, - // controller: controller, - // ), - ], + body: SafeArea( + top: false, + child: Stack( + children: [ + _buildBody(isDarkMode), + // 可拖拽的悬浮按钮 + // DraggableFloatingButton( + // isDarkMode: isDarkMode, + // controller: controller, + // ), + ], + ), ), ); }); @@ -72,64 +75,67 @@ class TranslationView extends GetView { Widget _buildFaceToFaceScaffold(bool isDarkMode) { return Scaffold( backgroundColor: isDarkMode ? AppColors.darkBackground : Colors.grey[50], - body: Stack( - children: [ - // 主要内容区域 - FaceToFaceLayout( - isDarkMode: isDarkMode, - controller: controller, - ), + body: SafeArea( + top: false, + child: Stack( + children: [ + // 主要内容区域 + FaceToFaceLayout( + isDarkMode: isDarkMode, + controller: controller, + ), - Positioned( - top: 2, - left: 0, - right: 0, - child: SafeArea( - top: true, - child: Container( - height: 56.h, - padding: EdgeInsets.symmetric(horizontal: 8.w), - color: Colors.transparent, - child: Align( - alignment: Alignment.centerLeft, - child: IconButton( - icon: Icon( - Icons.arrow_back_ios, - color: isDarkMode ? Colors.white : Colors.black, - size: 20.sp, + Positioned( + top: 2, + left: 0, + right: 0, + child: SafeArea( + top: true, + child: Container( + height: 56.h, + padding: EdgeInsets.symmetric(horizontal: 8.w), + color: Colors.transparent, + child: Align( + alignment: Alignment.centerLeft, + child: IconButton( + icon: Icon( + Icons.arrow_back_ios, + color: isDarkMode ? Colors.white : Colors.black, + size: 20.sp, + ), + onPressed: () => Get.back(), ), - onPressed: () => Get.back(), ), ), ), ), - ), - // 顶部按钮(倒过来) - Positioned( - top: 50.h, - left: 0, - right: 0, - child: Transform.rotate( - angle: 3.14159, // 180度旋转 - child: _buildFaceToFaceTopButton(isDarkMode), + // 顶部按钮(倒过来) + Positioned( + top: 50.h, + left: 0, + right: 0, + child: Transform.rotate( + angle: 3.14159, // 180度旋转 + child: _buildFaceToFaceTopButton(isDarkMode), + ), ), - ), - // 底部按钮 - Positioned( - bottom: 40.h, - left: 0, - right: 0, - child: _buildFaceToFaceBottomButton(isDarkMode), - ), + // 底部按钮 + Positioned( + bottom: 40.h, + left: 0, + right: 0, + child: _buildFaceToFaceBottomButton(isDarkMode), + ), - // 可拖拽的悬浮按钮 - 在所有模式下都显示 - // DraggableFloatingButton( - // isDarkMode: isDarkMode, - // controller: controller, - // ), - ], + // 可拖拽的悬浮按钮 - 在所有模式下都显示 + // DraggableFloatingButton( + // isDarkMode: isDarkMode, + // controller: controller, + // ), + ], + ), ), ); }