language_view.dart 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_screenutil/flutter_screenutil.dart';
  3. import 'package:get/get.dart';
  4. import 'package:nomo/app/base/base_view.dart';
  5. import 'package:nomo/app/widgets/click_opacity.dart';
  6. import 'package:nomo/app/widgets/ix_app_bar.dart';
  7. import 'package:nomo/config/theme/theme_extensions/theme_extension.dart';
  8. import '../../../../config/translations/strings_enum.dart';
  9. import '../controllers/language_controller.dart';
  10. class LanguageView extends BaseView<LanguageController> {
  11. const LanguageView({super.key});
  12. @override
  13. PreferredSizeWidget? get appBar => IXAppBar(title: Strings.language.tr);
  14. @override
  15. Widget buildContent(BuildContext context) {
  16. return SingleChildScrollView(
  17. child: Padding(
  18. padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 10.w),
  19. child: Container(
  20. decoration: BoxDecoration(
  21. color: Get.reactiveTheme.highlightColor,
  22. borderRadius: BorderRadius.circular(12.r),
  23. ),
  24. child: Obx(
  25. () => Column(
  26. children: controller.languages.asMap().entries.map((entry) {
  27. final index = entry.key;
  28. final language = entry.value;
  29. final isSelected =
  30. controller.selectedLanguage.value == language.code;
  31. return Column(
  32. children: [
  33. _buildLanguageOption(
  34. language: language,
  35. isSelected: isSelected,
  36. onTap: () => controller.selectLanguage(language.code),
  37. ),
  38. if (index < controller.languages.length - 1)
  39. _buildDivider(),
  40. ],
  41. );
  42. }).toList(),
  43. ),
  44. ),
  45. ),
  46. ),
  47. );
  48. }
  49. /// 构建语言选项
  50. Widget _buildLanguageOption({
  51. required LanguageInfo language,
  52. required bool isSelected,
  53. required VoidCallback onTap,
  54. }) {
  55. return ClickOpacity(
  56. onTap: onTap,
  57. child: Padding(
  58. padding: EdgeInsets.all(14.w),
  59. child: Row(
  60. children: [
  61. // 语言信息
  62. Expanded(
  63. child: Column(
  64. crossAxisAlignment: CrossAxisAlignment.start,
  65. children: [
  66. Text(
  67. language.name,
  68. style: TextStyle(
  69. fontSize: 14.sp,
  70. height: 1.4,
  71. fontWeight: FontWeight.w600,
  72. color: isSelected
  73. ? Get.reactiveTheme.shadowColor
  74. : Get.reactiveTheme.textTheme.bodyLarge!.color,
  75. ),
  76. ),
  77. // Text(
  78. // language.nativeName,
  79. // style: TextStyle(
  80. // fontSize: 12.sp,
  81. // height: 1.6,
  82. // color: Get.reactiveTheme.hintColor,
  83. // ),
  84. // ),
  85. ],
  86. ),
  87. ),
  88. // 选中指示器
  89. Container(
  90. width: 20.w,
  91. height: 20.w,
  92. decoration: BoxDecoration(
  93. shape: BoxShape.circle,
  94. color: isSelected
  95. ? Get.reactiveTheme.shadowColor
  96. : Colors.transparent,
  97. border: Border.all(
  98. color: isSelected
  99. ? Get.reactiveTheme.shadowColor
  100. : Colors.grey[400]!,
  101. width: 1.5.w,
  102. ),
  103. ),
  104. child: isSelected
  105. ? Icon(Icons.check, color: Colors.white, size: 16.w)
  106. : null,
  107. ),
  108. ],
  109. ),
  110. ),
  111. );
  112. }
  113. /// 构建分割线
  114. Widget _buildDivider() {
  115. return Divider(color: Get.reactiveTheme.dividerColor, height: 1.w);
  116. }
  117. }