main_news_page.dart 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter/services.dart';
  3. import 'package:flutter_riverpod/flutter_riverpod.dart';
  4. import 'package:flutter_screenutil/flutter_screenutil.dart';
  5. import 'package:news_app/ui/news/news_child_main_page.dart';
  6. import 'package:news_app/ui/search/search_bar_widget.dart';
  7. import '../../constant/color_res.dart';
  8. import '../../gen/assets.gen.dart';
  9. import '../../model/news_category_model.dart';
  10. import '../../provider/news_category_provider.dart';
  11. /// @author: bo.zeng
  12. /// @email: cnhbwds@gmail.com
  13. /// @date: 2025 2025/4/9 16:00
  14. /// @description:
  15. class MainNewsPage extends ConsumerStatefulWidget {
  16. const MainNewsPage({super.key});
  17. @override
  18. ConsumerState<MainNewsPage> createState() => _MainNewsPageState();
  19. }
  20. final newsCategoryProvider =
  21. NotifierProvider<NewsCategoryProvider, List<NewsCategoryModel>>(() {
  22. return NewsCategoryProvider();
  23. });
  24. final tabIndexProvider = StateProvider<int>((ref) => 0);
  25. final List<Color> _startColorList = [
  26. color343090,
  27. color5F59F7,
  28. color6592FD,
  29. color8C61FF,
  30. color44C2FD,
  31. color5F59F7,
  32. ];
  33. final List<Color> _middleColorList = [
  34. color343090,
  35. color5F59F7,
  36. color6592FD,
  37. color8C61FF,
  38. color44C2FD,
  39. color6379FB,
  40. ];
  41. class _MainNewsPageState extends ConsumerState<MainNewsPage>
  42. with AutomaticKeepAliveClientMixin, SingleTickerProviderStateMixin {
  43. TabController? _tabController;
  44. @override
  45. void initState() {
  46. super.initState();
  47. ref.read(newsCategoryProvider.notifier).fetchNewsCategoryList();
  48. }
  49. @override
  50. void dispose() {
  51. super.dispose();
  52. _tabController?.dispose();
  53. }
  54. @override
  55. Widget build(BuildContext context) {
  56. super.build(context);
  57. final result = ref.watch(newsCategoryProvider);
  58. var categoryList = result;
  59. if (result.length > 6) {
  60. categoryList = result.take(6).toList();
  61. }
  62. final tabIndex = ref.watch(tabIndexProvider);
  63. if (categoryList.isEmpty) {
  64. return const SizedBox.shrink();
  65. }
  66. // 初始化 tabController(只初始化一次)
  67. if (_tabController == null) {
  68. _tabController = TabController(length: categoryList.length, vsync: this);
  69. _tabController?.addListener(() {
  70. ref.read(tabIndexProvider.notifier).state = _tabController?.index ?? 0;
  71. });
  72. }
  73. return Scaffold(
  74. appBar: AppBar(
  75. backgroundColor: _startColorList[tabIndex],
  76. systemOverlayStyle: SystemUiOverlayStyle(
  77. statusBarColor: _middleColorList[tabIndex],
  78. statusBarIconBrightness: Brightness.light, // 状态栏图标颜色
  79. ),
  80. title: Row(
  81. spacing: 10.w,
  82. children: [
  83. Image.asset(Assets.images.logo.path, width: 70.w),
  84. Expanded(child: SearchBarWidget(tabIndex: 0)),
  85. ],
  86. ),
  87. bottom: TabBar(
  88. controller: _tabController,
  89. tabAlignment: TabAlignment.center,
  90. isScrollable: true,
  91. indicatorColor: Colors.white,
  92. dividerHeight: 0,
  93. labelColor: Colors.white,
  94. // 选中标签颜色
  95. unselectedLabelColor: Colors.white,
  96. // 未选中标签颜色
  97. labelStyle: TextStyle(
  98. fontWeight: FontWeight.bold, // 选中标签加粗
  99. fontSize: 16.0.sp,
  100. ),
  101. unselectedLabelStyle: TextStyle(
  102. fontWeight: FontWeight.normal, // 未选中标签不加粗
  103. fontSize: 16.0.sp,
  104. ),
  105. tabs: categoryList.map((item) => Tab(text: item.name)).toList(),
  106. ),
  107. ),
  108. body: Stack(
  109. children: [
  110. Positioned(
  111. child: Container(
  112. height: 100.h,
  113. decoration: BoxDecoration(
  114. gradient: LinearGradient(
  115. colors: [
  116. _startColorList[tabIndex],
  117. _middleColorList[tabIndex],
  118. Colors.white,
  119. ],
  120. begin: Alignment.topCenter,
  121. end: Alignment.bottomCenter,
  122. ),
  123. ),
  124. ),
  125. ),
  126. TabBarView(
  127. controller: _tabController,
  128. children: getListPage(categoryList),
  129. ),
  130. ],
  131. ),
  132. );
  133. }
  134. List<Widget> getListPage(List<NewsCategoryModel> items) {
  135. List<Widget> list = [];
  136. items.asMap().entries.forEach((element) {
  137. list.add(NewsChildMainPage(tabIndex: element.key));
  138. });
  139. return list;
  140. }
  141. @override
  142. bool get wantKeepAlive => true;
  143. }