基础组件库
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 

249 wiersze
7.5 KiB

  1. import 'package:event_bus/event_bus.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:pull_to_refresh/pull_to_refresh.dart';
  4. import 'package:provider/provider.dart';
  5. import 'package:flutter_bloc/flutter_bloc.dart';
  6. import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_notifier.dart';
  7. import 'package:zhiying_base_widget/widgets/empty/empty_widget.dart';
  8. import 'package:zhiying_base_widget/widgets/home/home_auth/home_auth.dart';
  9. import 'package:zhiying_base_widget/widgets/refresh/refresh_footer/refresh_footer.dart';
  10. import 'package:zhiying_base_widget/widgets/refresh/refresh_header/refresh_gif_header.dart';
  11. import 'package:zhiying_base_widget/widgets/refresh/refresh_header/refresh_header.dart';
  12. import 'package:zhiying_comm/zhiying_comm.dart';
  13. import 'bloc/custom_item_page_bloc.dart';
  14. import 'bloc/custom_item_page_state.dart';
  15. import 'bloc/custom_item_page_event.dart';
  16. import 'bloc/custom_item_page_repository.dart';
  17. import 'dart:ui';
  18. import 'package:zhiying_comm/util/custom_sliver_persistent_header_delegate.dart';
  19. ///
  20. /// 通用模块的分类导航下的子模块
  21. ///
  22. ///
  23. class CustomItemPage extends StatelessWidget {
  24. final Map<String, dynamic> data;
  25. final int tabIndex;
  26. final String modPid;
  27. final String modId;
  28. final bool needBuildStatus;
  29. CustomItemPage(this.data, this.tabIndex, this.modId, this.modPid, this.needBuildStatus);
  30. @override
  31. Widget build(BuildContext context) {
  32. return MultiProvider(
  33. providers: [
  34. ChangeNotifierProvider.value(value: MainPageNotifier()),
  35. ],
  36. child: BlocProvider<CustomItemPageBloc>(
  37. create: (_) => CustomItemPageBloc(CustomItemPageRepository(this.data, this.tabIndex, this.modId, this.modPid)),
  38. child: _CustomItemPageContainer(this.data, this.tabIndex, this.modId, this.modPid, this.needBuildStatus),
  39. ),
  40. );
  41. }
  42. }
  43. class _CustomItemPageContainer extends StatefulWidget {
  44. final Map<String, dynamic> data;
  45. final int tabIndex;
  46. final String modPid;
  47. final String modId;
  48. final bool needBuildStatus;
  49. const _CustomItemPageContainer(this.data, this.tabIndex, this.modId, this.modPid, this.needBuildStatus, {Key key}) : super(key: key);
  50. @override
  51. __CustomItemPageContainerState createState() => __CustomItemPageContainerState();
  52. }
  53. class __CustomItemPageContainerState extends State<_CustomItemPageContainer> with AutomaticKeepAliveClientMixin {
  54. @override
  55. bool get wantKeepAlive => true;
  56. ScrollController _controller;
  57. RefreshController _refreshController;
  58. final EventBus _eventBus = EventBus();
  59. /// 回到顶点
  60. void _scrollTop() {
  61. // _controller.jumpTo(0);
  62. _controller.animateTo(0, duration: Duration(milliseconds: 200), curve: Curves.linear);
  63. }
  64. /// 初始化
  65. void _initEvent() {
  66. BlocProvider.of<CustomItemPageBloc>(context).add(CustomItemPageInitEvent());
  67. }
  68. /// 刷新
  69. void _refreshEvent() {
  70. BlocProvider.of<CustomItemPageBloc>(context).add(CustomItemPageRefreshEvent());
  71. }
  72. /// 下拉更多
  73. void _loadEvent() {
  74. // BlocProvider.of<CustomItemPageBloc>(context).add(CustomItemPageLoadEvent());
  75. Provider.of<MainPageNotifier>(context, listen: false).loadMore();
  76. Future.delayed(Duration(milliseconds: 500), () => _refreshController?.loadComplete());
  77. }
  78. @override
  79. void initState() {
  80. _controller = ScrollController();
  81. _refreshController = RefreshController(initialRefresh: false);
  82. _initEvent();
  83. super.initState();
  84. }
  85. @override
  86. void dispose() {
  87. _controller?.dispose();
  88. _refreshController?.dispose();
  89. super.dispose();
  90. }
  91. @override
  92. Widget build(BuildContext context) {
  93. return BlocConsumer<CustomItemPageBloc, CustomItemPageState>(
  94. listener: (context, state) {},
  95. buildWhen: (prev, current) {
  96. if (current is CustomItemPageRefreshSuccessState) {
  97. _refreshController?.refreshCompleted(resetFooterState: true);
  98. return false;
  99. }
  100. if (current is CustomItemPageRefreshErrorState) {
  101. _refreshController?.refreshFailed();
  102. return false;
  103. }
  104. if (current is CustomItemPageLoadSuccessState) {
  105. _refreshController?.loadComplete();
  106. return false;
  107. }
  108. if (current is CustomItemPageLoadErrorState) {
  109. _refreshController?.loadNoData();
  110. return false;
  111. }
  112. if (current is CustomItemPageErrorState) {
  113. return false;
  114. }
  115. return true;
  116. },
  117. builder: (context, state) {
  118. if (state is CustomItemPageLoadedState) {
  119. if (EmptyUtil.isEmpty(state.model))
  120. return _buildEmptyWidget();
  121. else
  122. return _buildMainWidget(state.model);
  123. }
  124. if (state is CustomItemPageInitErrorState) {
  125. return _buildEmptyWidget();
  126. }
  127. return _buildSkeletonWidget();
  128. },
  129. );
  130. }
  131. /// 有数据
  132. Widget _buildMainWidget(final List<Map<String, dynamic>> model) {
  133. return MediaQuery.removePadding(
  134. context: context,
  135. removeTop: false,
  136. child: Stack(
  137. children: <Widget>[
  138. SmartRefresher(
  139. controller: _refreshController,
  140. enablePullDown: true,
  141. enablePullUp: true,
  142. onRefresh: _refreshEvent,
  143. onLoading: _loadEvent,
  144. header: RefreshGifHeader(),
  145. // footer: RefreshFooter(),
  146. child: CustomScrollView(
  147. controller: _controller,
  148. slivers: _buildContentWidgets(model),
  149. ),
  150. ),
  151. Align(
  152. alignment: Alignment.bottomCenter,
  153. child: Container( margin: const EdgeInsets.only(bottom: 8), child: _buildAuthWidget(model),), //_buildAuthWidget(model),
  154. )
  155. ],
  156. ),
  157. );
  158. }
  159. /// 根据widget的modName生成视图
  160. List<Widget> _buildContentWidgets(final List<Map<String, dynamic>> datas) {
  161. List<Widget> result = [];
  162. for (int i = 0; i < datas.length; i++) {
  163. WidgetModel item = WidgetModel.fromJson(Map<String, dynamic>.from(datas[i]));
  164. if(item.modName == 'audit_tip'){
  165. Logger.debug('授权组件,跳过');
  166. continue;
  167. }
  168. if(item.modName == 'product'){
  169. datas[i]['eventBus'] = _eventBus;
  170. }
  171. result.addAll(WidgetFactory.create(
  172. item.modName,
  173. isSliver: true,
  174. model: datas[i],
  175. ));
  176. }
  177. // if (widget.needBuildStatus) {
  178. // double top = MediaQueryData.fromWindow(window).padding.top;
  179. // result.insert(
  180. // 0,
  181. // SliverPersistentHeader(
  182. // pinned: false,
  183. // floating: false,
  184. // delegate: CustomSliverPersistentHeaderDelegate(max: top, min: top, child: Container(
  185. // // color: Colors.yellow,
  186. // color: HexColor.fromHex('#FFFF4242'),
  187. // )),
  188. // ));
  189. //
  190. // }
  191. return result;
  192. }
  193. /// 空数据
  194. Widget _buildEmptyWidget() {
  195. return SmartRefresher(
  196. controller: _refreshController,
  197. onRefresh: _refreshEvent,
  198. enablePullDown: true,
  199. child: Container(
  200. child: EmptyWidget(),
  201. ),
  202. );
  203. }
  204. /// 骨架图
  205. Widget _buildSkeletonWidget() {
  206. return Container();
  207. }
  208. /// 特殊的授权组件
  209. Widget _buildAuthWidget(final List<Map<String, dynamic>> datas){
  210. int length = datas?.length ?? 0;
  211. if(length == 0) return Container();
  212. Widget rlt;
  213. for (int i = 0; i < datas.length; i++) {
  214. WidgetModel item = WidgetModel.fromJson(Map<String, dynamic>.from(datas[i]));
  215. if(item.modName == 'audit_tip'){
  216. rlt = HomeAuth(datas[i]);
  217. break;
  218. }
  219. }
  220. return rlt ?? Container();
  221. }
  222. }