基础组件库
 
 
 
 
 

189 lines
5.4 KiB

  1. import 'package:flutter/material.dart';
  2. import 'package:pull_to_refresh/pull_to_refresh.dart';
  3. import 'package:provider/provider.dart';
  4. import 'package:flutter_bloc/flutter_bloc.dart';
  5. import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_notifier.dart';
  6. import 'package:zhiying_base_widget/widgets/refresh/refresh_footer/refresh_footer.dart';
  7. import 'package:zhiying_base_widget/widgets/refresh/refresh_header/refresh_header.dart';
  8. import 'package:zhiying_comm/zhiying_comm.dart';
  9. import 'bloc/custom_item_page_bloc.dart';
  10. import 'bloc/custom_item_page_state.dart';
  11. import 'bloc/custom_item_page_event.dart';
  12. import 'bloc/custom_item_page_repository.dart';
  13. ///
  14. /// 通用模块的分类导航下的子模块
  15. ///
  16. ///
  17. class CustomItemPage extends StatelessWidget {
  18. final Map<String, dynamic> data;
  19. final int tabIndex;
  20. final String modPid;
  21. final String modId;
  22. CustomItemPage(this.data, this.tabIndex, this.modId, this.modPid);
  23. @override
  24. Widget build(BuildContext context) {
  25. return MultiProvider(
  26. providers: [
  27. ChangeNotifierProvider.value(value: MainPageNotifier()),
  28. ],
  29. child: BlocProvider<CustomItemPageBloc>(
  30. create: (_) => CustomItemPageBloc(CustomItemPageRepository(this.data, this.tabIndex, this.modId, this.modPid)),
  31. child: _CustomItemPageContainer(
  32. this.data,
  33. this.tabIndex,
  34. this.modId,
  35. this.modPid,
  36. key: UniqueKey(),
  37. ),
  38. ),
  39. );
  40. }
  41. }
  42. class _CustomItemPageContainer extends StatefulWidget {
  43. final Map<String, dynamic> data;
  44. final int tabIndex;
  45. final String modPid;
  46. final String modId;
  47. const _CustomItemPageContainer(this.data, this.tabIndex, this.modId, this.modPid, {Key key}) : super(key: key);
  48. @override
  49. __CustomItemPageContainerState createState() => __CustomItemPageContainerState();
  50. }
  51. class __CustomItemPageContainerState extends State<_CustomItemPageContainer> with AutomaticKeepAliveClientMixin {
  52. @override
  53. bool get wantKeepAlive => true;
  54. ScrollController _controller;
  55. RefreshController _refreshController;
  56. /// 回到顶点
  57. void _scrollTop() {
  58. // _controller.jumpTo(0);
  59. _controller.animateTo(0, duration: Duration(milliseconds: 200), curve: Curves.linear);
  60. }
  61. /// 初始化
  62. void _initEvent() {
  63. BlocProvider.of<CustomItemPageBloc>(context).add(CustomItemPageInitEvent());
  64. }
  65. /// 刷新
  66. void _refreshEvent() {
  67. BlocProvider.of<CustomItemPageBloc>(context).add(CustomItemPageRefreshEvent());
  68. }
  69. /// 下拉更多
  70. void _loadEvent() {
  71. // BlocProvider.of<CustomItemPageBloc>(context).add(CustomItemPageLoadEvent());
  72. Provider.of<MainPageNotifier>(context, listen: false).loadMore();
  73. Future.delayed(Duration(seconds: 1),()=> _refreshController?.loadComplete());
  74. }
  75. @override
  76. void initState() {
  77. _controller = ScrollController();
  78. _refreshController = RefreshController(initialRefresh: false);
  79. _initEvent();
  80. super.initState();
  81. }
  82. @override
  83. void dispose() {
  84. _controller?.dispose();
  85. _refreshController?.dispose();
  86. super.dispose();
  87. }
  88. @override
  89. Widget build(BuildContext context) {
  90. return BlocConsumer<CustomItemPageBloc, CustomItemPageState>(
  91. listener: (context, state) {},
  92. buildWhen: (prev, current) {
  93. if (current is CustomItemPageRefreshSuccessState) {
  94. _refreshController?.refreshCompleted(resetFooterState: true);
  95. return false;
  96. }
  97. if (current is CustomItemPageRefreshErrorState) {
  98. _refreshController?.refreshFailed();
  99. return false;
  100. }
  101. if (current is CustomItemPageLoadSuccessState) {
  102. _refreshController?.loadComplete();
  103. return false;
  104. }
  105. if (current is CustomItemPageLoadErrorState) {
  106. _refreshController?.loadNoData();
  107. return false;
  108. }
  109. if (current is CustomItemPageErrorState) {
  110. return false;
  111. }
  112. return true;
  113. },
  114. builder: (context, state) {
  115. if (state is CustomItemPageLoadedState) {
  116. if (EmptyUtil.isEmpty(state.model))
  117. return _buildEmptyWidget();
  118. else
  119. return _buildMainWidget(state.model);
  120. }
  121. if (state is CustomItemPageInitErrorState) {
  122. return _buildEmptyWidget();
  123. }
  124. return _buildSkeletonWidget();
  125. },
  126. );
  127. }
  128. /// 有数据
  129. Widget _buildMainWidget(final List<Map<String, dynamic>> model) {
  130. return MediaQuery.removePadding(
  131. context: context,
  132. removeTop: true,
  133. child: SmartRefresher(
  134. controller: _refreshController,
  135. enablePullDown: true,
  136. enablePullUp: true,
  137. onRefresh: _refreshEvent,
  138. onLoading: _loadEvent,
  139. header: RefreshHeader(),
  140. footer: RefreshFooter(),
  141. child: CustomScrollView(
  142. controller: _controller,
  143. slivers: _buildContentWidgets(model),
  144. ),
  145. ),
  146. );
  147. }
  148. /// 根据widget的modName生成视图
  149. List<Widget> _buildContentWidgets(final List<Map<String, dynamic>> datas) {
  150. List<Widget> result = [];
  151. for (int i = 0; i < datas.length; i++) {
  152. WidgetModel item = WidgetModel.fromJson(Map<String, dynamic>.from(datas[i]));
  153. result.addAll(WidgetFactory.create(
  154. item.modName,
  155. isSliver: true,
  156. model: datas[i],
  157. ));
  158. }
  159. return result;
  160. }
  161. /// 空数据
  162. Widget _buildEmptyWidget() {
  163. return Container();
  164. }
  165. /// 骨架图
  166. Widget _buildSkeletonWidget() {
  167. return Container();
  168. }
  169. }