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

234 行
7.6 KiB

  1. import 'dart:convert';
  2. import 'dart:ui';
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:provider/provider.dart';
  6. import 'package:pull_to_refresh/pull_to_refresh.dart';
  7. import 'package:zhiying_base_widget/pages/main_page/main_page_bloc.dart';
  8. import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_bg_notifier.dart';
  9. import 'package:zhiying_base_widget/pages/main_page/notifier/main_page_notifier.dart';
  10. import 'package:zhiying_base_widget/widgets/home/home_auth/home_auth.dart';
  11. import 'package:zhiying_base_widget/widgets/mine/mine_nav/mine_nav_bg.dart';
  12. import 'package:zhiying_base_widget/widgets/others/mine_header_bg_widget.dart';
  13. import 'package:zhiying_base_widget/widgets/refresh/refresh_header/refresh_header.dart';
  14. import 'package:zhiying_comm/util/base_bloc.dart';
  15. import 'package:zhiying_comm/zhiying_comm.dart';
  16. class MainPage extends StatefulWidget {
  17. final Map<String, dynamic> data;
  18. MainPage(
  19. this.data, {
  20. Key key,
  21. }) : super(key: key);
  22. @override
  23. _MainPageState createState() => _MainPageState();
  24. }
  25. class _MainPageState extends State<MainPage> {
  26. @override
  27. Widget build(BuildContext context) {
  28. return MultiProvider(
  29. providers: [
  30. ChangeNotifierProvider.value(value: MainPageNotifier()),
  31. ChangeNotifierProvider.value(value: MainPageBgNotifier()),
  32. ],
  33. child: BlocProvider<MainPageBloc>(
  34. bloc: MainPageBloc(),
  35. child: _MainPageContainer(widget.data),
  36. ),
  37. );
  38. }
  39. }
  40. class _MainPageContainer extends StatefulWidget {
  41. final Map<String, dynamic> data;
  42. _MainPageContainer(this.data, {Key key}) : super(key: key);
  43. @override
  44. _MainPageContainerState createState() => _MainPageContainerState();
  45. }
  46. class _MainPageContainerState extends State<_MainPageContainer> {
  47. bool _isEnded = false;
  48. ScrollController _controller = ScrollController();
  49. MainPageBloc _bloc;
  50. RefreshController _refreshController = RefreshController(initialRefresh: false);
  51. Widget _floatWidget;
  52. void _onLoading() async {
  53. // await Future.delayed(Duration(milliseconds: 1000));
  54. // if (mounted) setState(() {});
  55. // _refreshController.loadComplete();
  56. }
  57. void _onRefresh() async {
  58. // await Future.delayed(Duration(milliseconds: 3000));
  59. // _refreshController.refreshCompleted();
  60. if (widget.data.containsKey('skip_identifier')) {
  61. _bloc.loadData(widget.data['skip_identifier']);
  62. }
  63. }
  64. @override
  65. void dispose() {
  66. _controller.dispose();
  67. _refreshController.dispose();
  68. super.dispose();
  69. }
  70. @override
  71. void initState() {
  72. _bloc = BlocProvider.of<MainPageBloc>(context);
  73. if (widget.data.containsKey('skip_identifier')) {
  74. _bloc.loadData(widget.data['skip_identifier']);
  75. }
  76. _controller.addListener(() {
  77. // print('${_controller.offset} ${_controller.position.maxScrollExtent}');
  78. if (_controller.offset >= _controller.position.maxScrollExtent && !_isEnded) {
  79. // 滑动到底部
  80. _isEnded = true;
  81. Provider.of<MainPageNotifier>(context, listen: false).loadMore();
  82. } else if (_controller.offset < _controller.position.maxScrollExtent && _isEnded) {
  83. _isEnded = false;
  84. Provider.of<MainPageNotifier>(context, listen: false).reset();
  85. }
  86. });
  87. super.initState();
  88. }
  89. @override
  90. Widget build(BuildContext context) {
  91. double top = MediaQueryData.fromWindow(window).padding.top;
  92. return StreamBuilder<List<Map<String, dynamic>>>(
  93. stream: _bloc.outData,
  94. builder: (BuildContext context, AsyncSnapshot snapshot) {
  95. print("mainPageBuild");
  96. List widgets = _createContent(context, snapshot.data ?? []);
  97. _refreshController.refreshCompleted();
  98. Widget bgWidget = validateBgWidget(context, snapshot.data ?? []);
  99. return Scaffold(
  100. backgroundColor: HexColor.fromHex("#fff9f9f9"),
  101. floatingActionButton: _floatWidget,
  102. floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
  103. body: MediaQuery.removePadding(
  104. removeTop: true,
  105. context: context,
  106. child: Container(
  107. width: double.infinity,
  108. child: Stack(
  109. fit: StackFit.passthrough,
  110. children: <Widget>[
  111. MineHeaderBgWidget(
  112. bgWidget: bgWidget,
  113. controller: _controller,
  114. ),
  115. SmartRefresher(
  116. enablePullDown: true,
  117. enablePullUp: false,
  118. header: RefreshHeader(
  119. offsetY: top,
  120. ),
  121. controller: _refreshController,
  122. onLoading: _onLoading,
  123. onRefresh: _onRefresh,
  124. child: CustomScrollView(
  125. controller: _controller,
  126. slivers: widgets,
  127. ),
  128. )
  129. ],
  130. ),
  131. ),
  132. ),
  133. );
  134. });
  135. }
  136. List<Widget> _createContent(BuildContext context, List<Map<String, dynamic>> datas) {
  137. List<Widget> list = List();
  138. for (int i = 0; i < datas.length; i++) {
  139. WidgetModel item = WidgetModel.fromJson(Map<String, dynamic>.from(datas[i]));
  140. print('item.modName ${item.modName}');
  141. if (item.modName == 'index_taobao_auth_tip') {
  142. _floatWidget = HomeAuth(datas[i]);
  143. continue;
  144. }
  145. list.addAll(WidgetFactory.create(
  146. item.modName,
  147. isSliver: true,
  148. model: datas[i],
  149. ));
  150. }
  151. if (list.length <= 0) {
  152. list.add(SliverToBoxAdapter(
  153. child: Container(
  154. height: 200,
  155. // child: Center(
  156. // child: Text('暂时无数据哦~'),
  157. // ),
  158. ),
  159. ));
  160. }
  161. return list;
  162. }
  163. ///处理特殊背景图
  164. Widget validateBgWidget(BuildContext context, List<Map<String, dynamic>> datas) {
  165. for (int i = 0; i < datas.length; i++) {
  166. WidgetModel item = WidgetModel.fromJson(Map<String, dynamic>.from(datas[i]));
  167. if (item.modName == "profile_background") {
  168. final double statusBarHeight = MediaQuery.of(context).padding.top;
  169. String url = json.decode(item.data)['img'];
  170. return Container(
  171. width: double.infinity,
  172. height: statusBarHeight + 250,
  173. child: CachedNetworkImage(
  174. imageUrl: url,
  175. fit: BoxFit.fitHeight,
  176. ),
  177. );
  178. }
  179. // if (item.modName == "member_info") {
  180. // final double statusBarHeight = MediaQuery.of(context).padding.top;
  181. // String url = json.decode(item.data)['bg_image'];
  182. // String bgColor = json.decode(item.data)['bg_color'];
  183. // return Container(
  184. // width: double.infinity,
  185. // height: statusBarHeight + 250,
  186. // color: HexColor.fromHex(bgColor ?? ""),
  187. // child: CachedNetworkImage(
  188. // imageUrl: url ?? "",
  189. // fit: BoxFit.fitHeight,
  190. // ),
  191. // );
  192. // }
  193. }
  194. if (_bloc.backgroundModel != null) {
  195. var headerBg = _bloc.backgroundModel.headerBg;
  196. return Container(
  197. height: double.tryParse(_bloc?.backgroundModel?.headerBg?.height)?? 0,
  198. decoration: BoxDecoration(
  199. gradient: LinearGradient(
  200. begin: Alignment.topCenter,
  201. end: Alignment.bottomCenter,
  202. colors: [HexColor.fromHex(headerBg?.mainColor ?? ""), HexColor.fromHex(headerBg?.assistColor ?? ""), HexColor.fromHex(headerBg?.minorColor ?? "")])),
  203. );
  204. }
  205. return null;
  206. }
  207. }