node_view.dart 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_screenutil/flutter_screenutil.dart';
  3. import 'package:get/get.dart';
  4. import 'package:nomo/config/theme/theme_extensions/theme_extension.dart';
  5. import 'package:nomo/utils/misc.dart';
  6. import '../../../../config/translations/strings_enum.dart';
  7. import '../../../base/base_view.dart';
  8. import '../../../widgets/click_opacity.dart';
  9. import '../../../widgets/ix_app_bar.dart';
  10. import '../controllers/node_controller.dart';
  11. import '../widgets/node_list.dart';
  12. class NodeView extends BaseView<NodeController> {
  13. const NodeView({super.key});
  14. @override
  15. PreferredSizeWidget? get appBar => IXAppBar(
  16. title: Strings.selectServer.tr,
  17. actions: [
  18. if (isDesktop)
  19. ClickOpacity(
  20. child: Padding(
  21. padding: EdgeInsets.symmetric(horizontal: 16.w),
  22. child: Icon(
  23. Icons.refresh,
  24. size: 20.w,
  25. color: Get.reactiveTheme.hintColor,
  26. ),
  27. ),
  28. onTap: () => controller.refreshLocations(),
  29. ),
  30. ],
  31. );
  32. @override
  33. Widget buildContent(BuildContext context) {
  34. final tabCount = controller.tabTextList.length;
  35. if (tabCount == 0) {
  36. return Center(child: Text(Strings.noData.tr));
  37. }
  38. return DefaultTabController(
  39. length: tabCount,
  40. initialIndex: controller.currentTabIndex, // 恢复上次的 Tab 位置
  41. child: Column(
  42. children: [
  43. if (isDesktop) _buildRefreshingIndicator(),
  44. _buildTabs(),
  45. Expanded(child: _buildTabBarView()),
  46. ],
  47. ),
  48. );
  49. }
  50. Widget _buildRefreshingIndicator() {
  51. return Obx(
  52. () => controller.isRefreshing
  53. ? LinearProgressIndicator(
  54. backgroundColor: Get.reactiveTheme.scaffoldBackgroundColor,
  55. minHeight: 2.w,
  56. valueColor: AlwaysStoppedAnimation<Color>(
  57. Get.reactiveTheme.primaryColor,
  58. ),
  59. )
  60. : const SizedBox(height: 2),
  61. );
  62. }
  63. Widget _buildTabs() {
  64. return TabBar(
  65. splashFactory: NoSplash.splashFactory,
  66. overlayColor: WidgetStateProperty.all(Colors.transparent),
  67. isScrollable: true,
  68. tabAlignment: TabAlignment.start,
  69. dividerColor: Get.reactiveTheme.dividerColor,
  70. indicatorSize: TabBarIndicatorSize.label,
  71. indicatorColor: Colors.transparent,
  72. // indicator: BoxDecoration(
  73. // color: Get.reactiveTheme.primaryColor,
  74. // borderRadius: BorderRadius.circular(8.r),
  75. // ),
  76. // indicatorWeight: 2,
  77. labelColor: Colors.white,
  78. unselectedLabelColor: Get.reactiveTheme.hintColor,
  79. labelStyle: TextStyle(
  80. fontSize: 14.sp,
  81. fontWeight: FontWeight.w400,
  82. fontFamily: 'FiraSans',
  83. ),
  84. unselectedLabelStyle: TextStyle(
  85. fontSize: 14.sp,
  86. fontWeight: FontWeight.w400,
  87. fontFamily: 'FiraSans',
  88. ),
  89. padding: EdgeInsets.symmetric(horizontal: 7.w, vertical: 10.w),
  90. labelPadding: EdgeInsets.symmetric(horizontal: 7.w, vertical: 0.w),
  91. // 监听 Tab 切换,保存当前索引
  92. onTap: (index) {
  93. controller.setTabSelected(index);
  94. },
  95. tabs: controller.tabTextList.map((e) {
  96. return Container(
  97. padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.w),
  98. decoration: BoxDecoration(
  99. color:
  100. controller.currentTabIndex == controller.tabTextList.indexOf(e)
  101. ? Get.reactiveTheme.primaryColor
  102. : Get.reactiveTheme.cardColor,
  103. borderRadius: BorderRadius.circular(8.r),
  104. ),
  105. child: Row(
  106. children: [
  107. Icon(
  108. controller.getTabIcon(controller.tabTextList.indexOf(e)),
  109. size: 14.w,
  110. ),
  111. 4.horizontalSpace,
  112. Text(e),
  113. ],
  114. ),
  115. );
  116. }).toList(),
  117. );
  118. }
  119. Widget _buildTabBarView() {
  120. return TabBarView(
  121. physics: const NeverScrollableScrollPhysics(), // 禁用左右滑动
  122. children: List.generate(
  123. controller.tabTextList.length,
  124. (index) => NodeList(tabIndex: index),
  125. ),
  126. );
  127. }
  128. }