基础组件库
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

team_page.dart 7.8 KiB

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