routingmode_view.dart 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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 '../../../constants/iconfont/iconfont.dart';
  10. import '../controllers/routingmode_controller.dart';
  11. class RoutingmodeView extends BaseView<RoutingmodeController> {
  12. const RoutingmodeView({super.key});
  13. @override
  14. PreferredSizeWidget? get appBar => IXAppBar(title: Strings.routingMode.tr);
  15. @override
  16. Widget buildContent(BuildContext context) {
  17. return 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. mainAxisSize: MainAxisSize.min,
  27. children: [
  28. _buildRoutingOption(
  29. mode: RoutingMode.smart,
  30. icon: IconFont.icon50,
  31. title: 'Smart',
  32. description:
  33. 'The local and VPN networks coexist, and the optimal route is selected intelligently.',
  34. isSelected: controller.selectedMode.value == RoutingMode.smart,
  35. onTap: () => controller.selectMode(RoutingMode.smart),
  36. ),
  37. _buildDivider(),
  38. _buildRoutingOption(
  39. mode: RoutingMode.global,
  40. icon: IconFont.icon51,
  41. title: 'Global',
  42. description:
  43. 'All traffic is routed through the VPN server to ensure maximum privacy and security.',
  44. isSelected: controller.selectedMode.value == RoutingMode.global,
  45. onTap: () => controller.selectMode(RoutingMode.global),
  46. ),
  47. ],
  48. ),
  49. ),
  50. ),
  51. );
  52. }
  53. /// 构建路由选项
  54. Widget _buildRoutingOption({
  55. required RoutingMode mode,
  56. required IconData icon,
  57. required String title,
  58. required String description,
  59. required bool isSelected,
  60. required VoidCallback onTap,
  61. }) {
  62. return ClickOpacity(
  63. onTap: onTap,
  64. child: Padding(
  65. padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 16.h),
  66. child: Row(
  67. crossAxisAlignment: CrossAxisAlignment.start,
  68. children: [
  69. // 图标
  70. Container(
  71. width: 30.w,
  72. height: 30.w,
  73. decoration: BoxDecoration(
  74. color: Get.reactiveTheme.shadowColor,
  75. borderRadius: BorderRadius.circular(8.r),
  76. ),
  77. child: Icon(icon, color: Colors.white, size: 20.w),
  78. ),
  79. 10.horizontalSpace,
  80. // 标题和描述
  81. Expanded(
  82. child: Column(
  83. crossAxisAlignment: CrossAxisAlignment.start,
  84. children: [
  85. Text(
  86. title,
  87. style: TextStyle(
  88. fontSize: 14.sp,
  89. height: 1.4,
  90. color: Get.reactiveTheme.textTheme.bodyLarge!.color,
  91. ),
  92. ),
  93. Text(
  94. description,
  95. style: TextStyle(
  96. fontSize: 12.sp,
  97. color: Get.reactiveTheme.hintColor,
  98. height: 1.6,
  99. ),
  100. ),
  101. ],
  102. ),
  103. ),
  104. 10.horizontalSpace,
  105. // 选中指示器
  106. Container(
  107. width: 20.w,
  108. height: 20.w,
  109. decoration: BoxDecoration(
  110. shape: BoxShape.circle,
  111. color: isSelected
  112. ? Get.reactiveTheme.shadowColor
  113. : Colors.transparent,
  114. border: Border.all(
  115. color: isSelected
  116. ? Get.reactiveTheme.shadowColor
  117. : Colors.grey[400]!,
  118. width: 1.5.w,
  119. ),
  120. ),
  121. child: isSelected
  122. ? Icon(Icons.check, color: Colors.white, size: 16.w)
  123. : null,
  124. ),
  125. ],
  126. ),
  127. ),
  128. );
  129. }
  130. /// 构建分割线
  131. Widget _buildDivider() {
  132. return Divider(color: Get.reactiveTheme.dividerColor, height: 1.w);
  133. }
  134. }