基础组件库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

team_page.dart 7.2 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:tab_indicator_styler/tab_indicator_styler.dart';
  4. import 'package:zhiying_base_widget/pages/team_page/bloc/team_bloc.dart';
  5. import 'package:zhiying_base_widget/pages/team_page/bloc/team_repository.dart';
  6. import 'package:zhiying_base_widget/pages/team_page/model/team_data_model.dart';
  7. import 'package:zhiying_base_widget/pages/team_page/model/team_style_model.dart';
  8. import 'package:zhiying_base_widget/pages/team_page/notifier/team_page_notifier.dart';
  9. import 'package:zhiying_base_widget/widgets/team/appbar/team_app_bar_widget.dart';
  10. import 'package:zhiying_base_widget/widgets/team/data/team_data_widet.dart';
  11. import 'package:zhiying_base_widget/widgets/team/fans_list/team_fans_widget.dart';
  12. import 'package:zhiying_base_widget/widgets/team/filter/team_filter_widget.dart';
  13. import 'package:zhiying_base_widget/widgets/team/input/team_input_widget.dart';
  14. import 'package:zhiying_base_widget/widgets/team/recommend/team_recommend_widget.dart';
  15. import 'package:zhiying_comm/util/custom_sliver_persistent_header_delegate.dart';
  16. import 'package:zhiying_comm/zhiying_comm.dart';
  17. import 'dart:ui';
  18. import 'package:provider/provider.dart';
  19. import 'package:flutter_bloc/flutter_bloc.dart';
  20. import 'team_page_sk.dart';
  21. ///
  22. /// 我的团队
  23. ///
  24. class TeamPage extends StatelessWidget {
  25. final Map<String, dynamic> data;
  26. const TeamPage(this.data);
  27. @override
  28. Widget build(BuildContext context) {
  29. return MultiProvider(
  30. providers: [
  31. ChangeNotifierProvider.value(value: TeamPageNotifier()),
  32. ],
  33. child: BlocProvider<TeamBloc>(
  34. create: (_) => TeamBloc(repository: TeamRepository())..add(TeamInitEvent(data)),
  35. child: _TeamPageContainer(),
  36. ),
  37. );
  38. }
  39. }
  40. class _TeamPageContainer extends StatefulWidget {
  41. @override
  42. _TeamPageContainerState createState() => _TeamPageContainerState();
  43. }
  44. class _TeamPageContainerState extends State<_TeamPageContainer> {
  45. TabController _controller;
  46. // TabController 监听
  47. void _tabChangeListener(){
  48. if (!_controller.indexIsChanging) {
  49. Provider.of<TeamPageNotifier>(context, listen: false).updateTabIndex(_controller?.index ?? 0);
  50. }
  51. }
  52. @override
  53. Widget build(BuildContext context) {
  54. return BlocConsumer<TeamBloc, TeamState>(
  55. listener: (context, state) {},
  56. buildWhen: (prov, current) {
  57. if (current is TeamErrorState) {
  58. return false;
  59. }
  60. return true;
  61. },
  62. builder: (context, state) {
  63. print('TeamPage state === $state, ');
  64. if (state is TeamLoadedState) {
  65. _initTabController(state?.styleModel);
  66. return _getMainWidget(state?.styleModel, state?.dataModel);
  67. }
  68. /// 骨架屏幕
  69. return TeamPageSkeleton();
  70. },
  71. );
  72. }
  73. @override
  74. void initState() {
  75. // _controller = TabController(length: tabTitle.length, vsync: ScrollableState());
  76. super.initState();
  77. }
  78. void _initTabController(TeamStyleModel styleModel) {
  79. if (null == _controller) {
  80. _controller = TabController(length: styleModel?.userLvTabs?.length ?? 0, vsync: ScrollableState());
  81. _controller.addListener(_tabChangeListener);
  82. }
  83. }
  84. @override
  85. void dispose() {
  86. _controller?.removeListener(_tabChangeListener);
  87. _controller?.dispose();
  88. super.dispose();
  89. }
  90. /// 主体视图
  91. Widget _getMainWidget(TeamStyleModel styleModel, TeamDataModel dataModel) {
  92. return Scaffold(
  93. resizeToAvoidBottomPadding: false,
  94. resizeToAvoidBottomInset: false,
  95. backgroundColor: HexColor.fromHex(styleModel?.bgColor ?? '#F9F9F9'),
  96. body: NestedScrollView(
  97. headerSliverBuilder: (context, bool) {
  98. return [
  99. /// 头部Bar
  100. TeamAppBarWidget(styleModel),
  101. /// 我的推荐人
  102. SliverToBoxAdapter(child: TeamRecommendWidget(styleModel, dataModel)),
  103. /// 数据
  104. SliverToBoxAdapter(child: TeamDataWidget(styleModel, dataModel)),
  105. /// 间距
  106. SliverToBoxAdapter(child: SizedBox(height: 8)),
  107. /// 输入框
  108. SliverPersistentHeader(delegate: CustomSliverPersistentHeaderDelegate(min: 34, max: 34, child: TeamInputWidget(styleModel, _controller)), pinned: true),
  109. /// 悬停TabBar
  110. SliverPersistentHeader(
  111. delegate: new _SliverTabBarDelegate(
  112. tabBar: TabBar(
  113. isScrollable: false,
  114. labelStyle: TextStyle(fontWeight: FontWeight.bold, fontSize: 13),
  115. unselectedLabelStyle: TextStyle(fontSize: 13),
  116. indicator: MaterialIndicator(
  117. height: 2,
  118. topLeftRadius: 8,
  119. topRightRadius: 8,
  120. bottomLeftRadius: 8,
  121. bottomRightRadius: 8,
  122. color: HexColor.fromHex(styleModel?.userLvTabsLineColor ?? '#F94B47'),
  123. horizontalPadding: 30,
  124. ),
  125. controller: _controller,
  126. // tabs: tabTitle.map((f) => Tab(text: f)).toList(),
  127. tabs: styleModel.userLvTabs
  128. .map((item) => Tab(
  129. text: item.name,
  130. ))
  131. .toList(),
  132. indicatorColor: Colors.red,
  133. unselectedLabelColor: HexColor.fromHex(styleModel?.userLvTabsNameColor ?? '#999999'),
  134. labelColor: HexColor.fromHex(styleModel?.userLvTabsNameSelectedColor ?? '#000000'),
  135. ),
  136. ),
  137. pinned: true,
  138. ),
  139. /// 筛选条件
  140. SliverPersistentHeader(delegate: CustomSliverPersistentHeaderDelegate(max: 32.5, min: 32.5, child: TeamFilterWidget(styleModel)), pinned: true),
  141. ];
  142. },
  143. body: MediaQuery.removePadding(
  144. removeTop: true,
  145. context: context,
  146. // child: TabBarView(controller: _controller, children: tabTitle.map((s) => TeamFansWidget(styleModel)).toList()),
  147. child: TabBarView(
  148. controller: _controller,
  149. children: _buildTabBarView(styleModel),
  150. // children: styleModel.userLvTabs.map((item) => TeamFansWidget(styleModel, item.type, )).toList(),
  151. ),
  152. ),
  153. ),
  154. );
  155. }
  156. /// 创建TabBarView
  157. List<Widget> _buildTabBarView(TeamStyleModel styleModel){
  158. List<Widget> lists = [];
  159. int length = styleModel?.userLvTabs?.length ?? 0;
  160. if(length > 0) {
  161. for (int i = 0; i < styleModel.userLvTabs.length; i ++) {
  162. UserLvTabs item = styleModel.userLvTabs[i];
  163. lists.add(TeamFansWidget(styleModel, item.type, i));
  164. }
  165. }else{
  166. lists.add(Container());
  167. }
  168. return lists;
  169. }
  170. }
  171. class _SliverTabBarDelegate extends SliverPersistentHeaderDelegate {
  172. final TabBar tabBar;
  173. const _SliverTabBarDelegate({this.tabBar}) : assert(tabBar != null);
  174. @override
  175. Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
  176. return Container(
  177. color: Colors.white,
  178. child: tabBar,
  179. );
  180. }
  181. @override
  182. bool shouldRebuild(_SliverTabBarDelegate oldDelegate) {
  183. return false;
  184. }
  185. @override
  186. double get maxExtent => tabBar.preferredSize.height;
  187. @override
  188. double get minExtent => tabBar.preferredSize.height;
  189. }