From 893739b5d0b5302bb88753db63d978a2241db77d Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Tue, 28 Oct 2025 17:09:30 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E6=96=87=E6=9C=AC=E7=BF=BB=E8=AF=91):?= =?UTF-8?q?=20=E9=87=8D=E6=9E=84=E8=AF=AD=E8=A8=80=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=99=A8=E6=A0=B7=E5=BC=8F=E4=B8=8E=E5=AF=B9=E8=AF=9D=E6=A1=86?= =?UTF-8?q?=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将语言选择器移至AppBar底部并统一胶囊样式 - 重写语言选择对话框为侧边弹出样式 - 使用统一颜色主题和圆角尺寸 - 优化暗黑模式下的显示效果 --- .../text_translation_controller.dart | 221 +++++++++++++----- .../views/text_translation_view.dart | 128 ++++++---- 2 files changed, 243 insertions(+), 106 deletions(-) diff --git a/lib/modules/text_translation/controllers/text_translation_controller.dart b/lib/modules/text_translation/controllers/text_translation_controller.dart index 1fcbb6a2c..3c7af49a2 100644 --- a/lib/modules/text_translation/controllers/text_translation_controller.dart +++ b/lib/modules/text_translation/controllers/text_translation_controller.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; import '../../../data/services/volcano_translation_service.dart'; import '../../../data/services/language_manager.dart'; @@ -318,75 +319,169 @@ class TextTranslationController extends GetxController { translatedText.value = ''; } - /// 显示语言选择对话框 + /// 显示语言选择对话框(统一与其它翻译模式的样式) void showLanguageSelector({required bool isSourceLanguage}) { - Get.bottomSheet( - Container( - height: Get.height * 0.6, - decoration: const BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.vertical(top: Radius.circular(20)), - ), - child: Column( - children: [ - Container( - padding: const EdgeInsets.all(16), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - isSourceLanguage - ? 'sourceLanguage'.tr - : 'targetLanguage'.tr, - style: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), + final isDarkMode = Theme.of(Get.context!).brightness == Brightness.dark; + + Get.dialog(Dialog( + backgroundColor: isDarkMode ? Colors.grey[900] : Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16.r), // 统一圆角尺寸 + ), + alignment: + isSourceLanguage ? Alignment.centerLeft : Alignment.centerRight, + insetPadding: EdgeInsets.symmetric(horizontal: 10.w), + child: SizedBox( + width: 0.4.sw, + child: Padding( + padding: EdgeInsets.all(12.w), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 标题区域 + Padding( + padding: EdgeInsets.symmetric(horizontal: 8.w), + child: Text( + isSourceLanguage + ? 'selectSourceLanguage'.tr // 翻译键代表的中文文本内容 + : 'selectTargetLanguage'.tr, // 翻译键代表的中文文本内容 + style: TextStyle( + fontSize: 18.sp, + fontWeight: FontWeight.w600, + color: isDarkMode ? Colors.white : Colors.black87, ), - IconButton( - onPressed: () => Get.back(), - icon: const Icon(Icons.close), + ), + ), + SizedBox(height: 16.h), + + // 语言列表区域 + Container( + constraints: BoxConstraints(maxHeight: 0.5.sh), + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: List.generate( + isSourceLanguage + ? (supportedLanguages.length + 1) + : supportedLanguages.length, + (index) { + // 源语言下首项为“自动检测” + final displayText = isSourceLanguage && index == 0 + ? 'autoDetect'.tr // 翻译键代表的中文文本内容 + : (isSourceLanguage + ? supportedLanguages[index - 1] + : supportedLanguages[index]); + final valueText = isSourceLanguage && index == 0 + ? '自动检测' + : (isSourceLanguage + ? supportedLanguages[index - 1] + : supportedLanguages[index]); + + final isSelected = isSourceLanguage + ? valueText == sourceLanguageChineseName.value + : valueText == targetLanguageChineseName.value; + + return GestureDetector( + onTap: () { + if (isSourceLanguage) { + setSourceLanguage(valueText); + } else { + setTargetLanguage(valueText); + } + Get.back(); + }, + child: Container( + margin: EdgeInsets.only(bottom: 10.h), + padding: EdgeInsets.all(10.w), + decoration: BoxDecoration( + color: isSelected + ? (isDarkMode + ? const Color(0xFF6200EE) + .withOpacity(0.2) + : Colors.blue.withOpacity(0.1)) + : (isDarkMode + ? Colors.white.withOpacity(0.05) + : Colors.grey[200]!), + borderRadius: BorderRadius.circular(12.r), + border: Border.all( + color: isSelected + ? (isDarkMode + ? const Color(0xFF6200EE) + : Colors.blue) + : (isDarkMode + ? Colors.white.withOpacity(0.05) + : Colors.grey[200]!), + width: 1, + ), + ), + child: Row( + children: [ + // 语言名称(中文名直接显示不进行翻译) + Expanded( + child: Text( + displayText, + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.w500, + color: isDarkMode + ? Colors.white + : Colors.black87, + overflow: TextOverflow.ellipsis, + ), + ), + ), + // 选中指示器 + Container( + width: 24.w, + height: 24.w, + decoration: BoxDecoration( + color: isSelected + ? (isDarkMode + ? const Color(0xFF6200EE) + : Colors.blue) + : (isDarkMode + ? Colors.white.withOpacity(0.1) + : Colors.grey[300]), + shape: BoxShape.circle, + ), + child: isSelected + ? Icon( + Icons.check, + size: 16.w, + color: Colors.white, + ) + : null, + ), + ], + ), + ), + ); + }, + ), ), - ], + ), ), - ), - const Divider(height: 1), - Expanded( - child: ListView.builder( - itemCount: (isSourceLanguage - ? (supportedLanguages.length + 1) - : supportedLanguages.length), - itemBuilder: (context, index) { - final language = isSourceLanguage - ? (index == 0 - ? '自动检测' - : supportedLanguages[index - 1]) - : supportedLanguages[index]; - final isSelected = isSourceLanguage - ? language == sourceLanguageChineseName.value - : language == targetLanguageChineseName.value; - - return ListTile( - title: Text(language), - trailing: isSelected - ? const Icon(Icons.check, color: Colors.blue) - : null, - onTap: () { - if (isSourceLanguage) { - setSourceLanguage(language); - } else { - setTargetLanguage(language); - } - Get.back(); - }, - ); - }, + SizedBox(height: 16.h), + + // 取消按钮 + Align( + alignment: Alignment.centerRight, + child: TextButton( + onPressed: () => Get.back(), + child: Text( + 'cancel'.tr, // 翻译键代表的中文文本内容 + style: TextStyle( + color: + isDarkMode ? const Color(0xFF6200EE) : Colors.blue, + ), + ), + ), ), - ), - ], + ], + ), ), ), - isScrollControlled: true, - ); + )); } } diff --git a/lib/modules/text_translation/views/text_translation_view.dart b/lib/modules/text_translation/views/text_translation_view.dart index 561c7d2f5..314bb78b1 100644 --- a/lib/modules/text_translation/views/text_translation_view.dart +++ b/lib/modules/text_translation/views/text_translation_view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import '../../../core/theme/app_colors.dart'; import '../controllers/text_translation_controller.dart'; @@ -21,10 +22,6 @@ class TextTranslationView extends GetView { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 语言选择区域 - _buildLanguageSelector(isDarkMode), - SizedBox(height: 20.h), - // 输入区域 _buildInputSection(isDarkMode), SizedBox(height: 20.h), @@ -74,67 +71,112 @@ class TextTranslationView extends GetView { tooltip: 'clearInput'.tr, ), ], + bottom: PreferredSize( + preferredSize: Size.fromHeight(50.h), + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.h), + child: _buildLanguageSelector(isDarkMode), + ), + ), ); } - /// 构建语言选择器 + /// 构建语言选择器(统一与其它翻译模式的样式) Widget _buildLanguageSelector(bool isDarkMode) { return Container( - padding: EdgeInsets.all(16.w), + height: 44.h, + padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 6.h), decoration: BoxDecoration( - color: isDarkMode ? Colors.grey[900] : Colors.white, - borderRadius: BorderRadius.circular(12.r), + color: isDarkMode ? AppColors.cardBackground : Colors.white, boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.05), - blurRadius: 10, + color: Colors.black.withOpacity(0.1), + blurRadius: 4, offset: const Offset(0, 2), ), + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 4, + offset: const Offset(0, -2), + ), ], ), - child: Column( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, children: [ - // 源语言选择 - Obx(() => _buildLanguageButton( - label: 'sourceLanguage'.tr, - selectedLanguage: controller.sourceLanguageChineseName.value, - onTap: () => - controller.showLanguageSelector(isSourceLanguage: true), - isDarkMode: isDarkMode, - )), - - SizedBox(height: 12.h), - - // 交换语言按钮 - Center( + // 源语言选择(与面对面模式一致的胶囊样式) + Expanded( child: GestureDetector( - onTap: controller.swapLanguages, + onTap: () => + controller.showLanguageSelector(isSourceLanguage: true), child: Container( - width: 40.w, - height: 40.w, + padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h), decoration: BoxDecoration( - color: Colors.blue.withOpacity(0.1), - shape: BoxShape.circle, - ), - child: Icon( - Icons.swap_vert, - color: Colors.blue, - size: 20.sp, + color: isDarkMode + ? Colors.white.withOpacity(0.1) + : Colors.grey[100], + borderRadius: BorderRadius.circular(16.r), ), + child: Obx(() => Text( + controller.sourceLanguageChineseName.value, + style: TextStyle( + fontSize: 15.sp, + fontWeight: FontWeight.w600, + color: isDarkMode ? Colors.white : Colors.black, + ), + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + )), ), ), ), - SizedBox(height: 12.h), + // 语言互换按钮(统一样式与颜色) + GestureDetector( + onTap: controller.swapLanguages, + child: Container( + margin: EdgeInsets.symmetric(horizontal: 8.w), + padding: EdgeInsets.all(4.r), + decoration: BoxDecoration( + color: isDarkMode + ? AppColors.primary.withOpacity(0.2) + : Colors.blue[50], + shape: BoxShape.circle, + ), + child: Icon( + Icons.swap_horiz, + color: isDarkMode ? AppColors.primary : Colors.blue, + size: 20.sp, + ), + ), + ), - // 目标语言选择 - Obx(() => _buildLanguageButton( - label: 'targetLanguage'.tr, - selectedLanguage: controller.targetLanguageChineseName.value, - onTap: () => - controller.showLanguageSelector(isSourceLanguage: false), - isDarkMode: isDarkMode, - )), + // 目标语言选择(与面对面模式一致的胶囊样式) + Expanded( + child: GestureDetector( + onTap: () => + controller.showLanguageSelector(isSourceLanguage: false), + child: Container( + padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h), + decoration: BoxDecoration( + color: isDarkMode + ? Colors.white.withOpacity(0.1) + : Colors.grey[100], + borderRadius: BorderRadius.circular(16.r), + ), + child: Obx(() => Text( + controller.targetLanguageChineseName.value, + style: TextStyle( + fontSize: 15.sp, + fontWeight: FontWeight.w600, + color: isDarkMode ? Colors.white : Colors.black, + ), + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + )), + ), + ), + ), ], ), );