基础组件库
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.
 
 
 
 
 

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