theme_view.dart 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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/theme_controller.dart';
  10. class ThemeView extends BaseView<ThemeController> {
  11. const ThemeView({super.key});
  12. @override
  13. PreferredSizeWidget? get appBar => IXAppBar(title: Strings.theme.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.themeModes.asMap().entries.map((entry) {
  27. final index = entry.key;
  28. final themeMode = entry.value;
  29. final isSelected =
  30. controller.selectedMode.value == themeMode.code;
  31. return Column(
  32. children: [
  33. _buildThemeOption(
  34. themeMode: themeMode,
  35. isSelected: isSelected,
  36. onTap: () => controller.selectThemeMode(themeMode.code),
  37. ),
  38. if (index < controller.themeModes.length - 1)
  39. _buildDivider(),
  40. ],
  41. );
  42. }).toList(),
  43. ),
  44. ),
  45. ),
  46. ),
  47. );
  48. }
  49. /// 构建主题选项
  50. Widget _buildThemeOption({
  51. required ThemeModeInfo themeMode,
  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: Text(
  64. themeMode.name,
  65. style: TextStyle(
  66. fontSize: 14.sp,
  67. height: 1.4,
  68. fontWeight: FontWeight.w600,
  69. color: isSelected
  70. ? Get.reactiveTheme.shadowColor
  71. : Get.reactiveTheme.textTheme.bodyLarge!.color,
  72. ),
  73. ),
  74. ),
  75. // 选中指示器
  76. Container(
  77. width: 20.w,
  78. height: 20.w,
  79. decoration: BoxDecoration(
  80. shape: BoxShape.circle,
  81. color: isSelected
  82. ? Get.reactiveTheme.shadowColor
  83. : Colors.transparent,
  84. border: Border.all(
  85. color: isSelected
  86. ? Get.reactiveTheme.shadowColor
  87. : Colors.grey[400]!,
  88. width: 1.5.w,
  89. ),
  90. ),
  91. child: isSelected
  92. ? Icon(Icons.check, color: Colors.white, size: 16.w)
  93. : null,
  94. ),
  95. ],
  96. ),
  97. ),
  98. );
  99. }
  100. /// 构建分割线
  101. Widget _buildDivider() {
  102. return Divider(color: Get.reactiveTheme.dividerColor, height: 1.w);
  103. }
  104. }