import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import '../../../core/theme/app_colors.dart'; /// 通用语言选择栏组件 /// - 统一源/目标语言胶囊样式与交换按钮样式 /// - 通过函数读取语言显示文本,以便模块内保持最小改动 /// - 文案默认走 .tr,本地化显示语言名称(翻译键代表的中文文本内容) class LanguageSelectorBar extends StatelessWidget { const LanguageSelectorBar({ Key? key, required this.sourceText, required this.targetText, required this.onTapSource, required this.onTapTarget, required this.onSwap, this.translateLanguageNames = true, this.fontSizeSp = 15, this.sourceSuffix, this.targetSuffix, }) : super(key: key); /// 返回源语言显示文本(建议返回语言中文名或翻译键) final String Function() sourceText; /// 返回目标语言显示文本(建议返回语言中文名或翻译键) final String Function() targetText; /// 源语言点击事件(打开语言选择弹窗) final VoidCallback onTapSource; /// 目标语言点击事件(打开语言选择弹窗) final VoidCallback onTapTarget; /// 语言交换事件 final VoidCallback onSwap; /// 是否将语言名称作为翻译键进行翻译(翻译键代表的中文文本内容) final bool translateLanguageNames; /// 字号(sp单位),默认 15,与语音翻译一致 final double fontSizeSp; /// 源语言后缀(可选),用于追加图标等 final Widget? sourceSuffix; /// 目标语言后缀(可选),用于追加图标等 final Widget? targetSuffix; @override Widget build(BuildContext context) { final isDarkMode = Get.isDarkMode; final capsuleBg = isDarkMode ? Colors.white.withOpacity(0.1) : Colors.grey[100]; final textColor = isDarkMode ? Colors.white : Colors.black; final swapBg = isDarkMode ? AppColors.primary.withOpacity(0.2) : Colors.blue[50]; final swapIconColor = isDarkMode ? AppColors.primary : Colors.blue; // 规范化特殊项的翻译键,例如:自动检测 -> autoDetect(对应中文:自动检测) String _normalizeKey(String text) { switch (text) { case '自动检测': return 'autoDetect'; default: return text; // 其他保持原值,由 .tr 决定是否命中 } } return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ // 源语言胶囊 Expanded( child: GestureDetector( onTap: onTapSource, child: Container( padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h), decoration: BoxDecoration( color: capsuleBg, borderRadius: BorderRadius.circular(16.r), ), child: Obx(() { final raw = sourceText(); final text = translateLanguageNames ? _normalizeKey(raw) : raw; return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Flexible( child: Text( translateLanguageNames ? text.tr : text, style: TextStyle( fontSize: fontSizeSp.sp, fontWeight: FontWeight.w600, color: textColor, ), textAlign: TextAlign.center, overflow: TextOverflow.ellipsis, ), ), if (sourceSuffix != null) ...[ SizedBox(width: 4.w), sourceSuffix!, ], ], ); }), ), ), ), // 语言互换按钮 GestureDetector( onTap: onSwap, child: Container( margin: EdgeInsets.symmetric(horizontal: 8.w), padding: EdgeInsets.all(4.r), decoration: BoxDecoration( color: swapBg, shape: BoxShape.circle, ), child: Icon( Icons.swap_horiz, color: swapIconColor, size: 20.sp, ), ), ), // 目标语言胶囊 Expanded( child: GestureDetector( onTap: onTapTarget, child: Container( padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h), decoration: BoxDecoration( color: capsuleBg, borderRadius: BorderRadius.circular(16.r), ), child: Obx(() { final raw = targetText(); final text = translateLanguageNames ? _normalizeKey(raw) : raw; return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Flexible( child: Text( translateLanguageNames ? text.tr : text, style: TextStyle( fontSize: fontSizeSp.sp, fontWeight: FontWeight.w600, color: textColor, ), textAlign: TextAlign.center, overflow: TextOverflow.ellipsis, ), ), if (targetSuffix != null) ...[ SizedBox(width: 4.w), targetSuffix!, ], ], ); }), ), ), ), ], ); } }