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

224 lines
6.7 KiB

  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_bloc/flutter_bloc.dart';
  4. import 'package:cached_network_image/cached_network_image.dart';
  5. import 'package:zhiying_comm/zhiying_comm.dart';
  6. import 'bloc/bloc.dart';
  7. import 'custom_notice_sk.dart';
  8. import 'package:zhiying_base_widget/widgets/base_state/base_state.dart';
  9. ///
  10. /// 公告滚动widget
  11. ///
  12. class CustomNoticeWidget extends StatefulWidget {
  13. final Map<String, dynamic> model;
  14. const CustomNoticeWidget(this.model);
  15. @override
  16. _CustomNoticeWidgetState createState() => _CustomNoticeWidgetState();
  17. }
  18. class _CustomNoticeWidgetState extends BaseWidgetState<CustomNoticeWidget> {
  19. CustomNoticeModel model;
  20. CustomNoticeRepository _repository;
  21. /// 子item点击事件
  22. void _itemOnClick(CustomNoticeModel model) {
  23. if (pageIndex == model.listStyle.length) {
  24. pageIndex = 0;
  25. }
  26. print('===== $pageIndex');
  27. NoticeListStyle item = model.listStyle[pageIndex];
  28. _itemJump(item);
  29. }
  30. /// 子item跳转
  31. void _itemJump(NoticeListStyle model) {
  32. print('${model?.contentText}');
  33. RouterUtil.route(model, model.toJson(), context);
  34. }
  35. @override
  36. void refreshWidget(String value) {
  37. setState(() {
  38. model = _repository.fetchParentData(widget?.model);
  39. });
  40. }
  41. @override
  42. void initState() {
  43. _repository = new CustomNoticeRepository();
  44. model = _repository.fetchParentData(widget?.model);
  45. super.initState();
  46. }
  47. @override
  48. void dispose() {
  49. model = null;
  50. _repository = null;
  51. super.dispose();
  52. }
  53. @override
  54. Widget build(BuildContext context) {
  55. if (!EmptyUtil.isEmpty(model))
  56. return _getMainWidget(model);
  57. else
  58. return CustomNoticeSkeleton();
  59. }
  60. /// 主体页面
  61. Widget _getMainWidget(CustomNoticeModel model) {
  62. return Container(
  63. width: double.infinity,
  64. decoration: BoxDecoration(
  65. color: HexColor.fromHex(model?.bgColor),
  66. //color: Colors.orangeAccent,
  67. borderRadius: BorderRadius.only(
  68. topRight: Radius.circular(ParseUtil.stringParseDouble(model?.topRightRadius, defVal: 7.5)),
  69. topLeft: Radius.circular(ParseUtil.stringParseDouble(model?.topLeftRadius, defVal: 7.5)),
  70. bottomLeft: Radius.circular(ParseUtil.stringParseDouble(model?.bottomLeftRadius, defVal: 7.5)),
  71. bottomRight: Radius.circular(ParseUtil.stringParseDouble(model?.bottomRightRadius, defVal: 7.5)),
  72. )),
  73. margin: EdgeInsets.only(
  74. top: ParseUtil.stringParseDouble(model?.topMargin),
  75. left: ParseUtil.stringParseDouble(model?.leftRightMargin),
  76. right: ParseUtil.stringParseDouble(model?.leftRightMargin)),
  77. padding: EdgeInsets.symmetric(horizontal: 7.5, vertical: 7.5),
  78. child: Container(
  79. decoration: BoxDecoration(borderRadius: BorderRadius.circular(7.5), color: HexColor.fromHex(model?.outsideBgColor ?? '#F6F6F6')),
  80. padding: const EdgeInsets.only(top: 8, bottom: 8, left: 12, right: 8),
  81. width: double.infinity,
  82. child: _getChildWidget(model),
  83. ),
  84. );
  85. }
  86. var pageIndex = 0;
  87. Widget _getChildWidget(CustomNoticeModel model) {
  88. return GestureDetector(
  89. onTap: () => _itemOnClick(model),
  90. behavior: HitTestBehavior.opaque,
  91. child: Row(
  92. children: <Widget>[
  93. /// 图片
  94. // Container(width: 52, height: 13, color: Colors.red),
  95. CachedNetworkImage(
  96. imageUrl: model?.appNameImg ?? '',
  97. width: 52,
  98. ),
  99. const SizedBox(width: 14),
  100. /// 文字
  101. Expanded(
  102. child: Container(
  103. width: double.infinity,
  104. height: 15,
  105. alignment: Alignment.centerLeft,
  106. // color: Colors.yellowAccent,
  107. child: MarqueeWidget(
  108. model?.listStyle?.length ?? 0,
  109. (BuildContext context, int index) {
  110. NoticeListStyle item = model.listStyle[index];
  111. return Align(alignment: Alignment.centerLeft, child: Text('${item?.contentText}', style: TextStyle(color: HexColor.fromHex(model?.textColor), fontSize: 12)));
  112. },
  113. onPageChanged: (index) => pageIndex = index,
  114. ),
  115. ),
  116. ),
  117. const SizedBox(width: 14),
  118. /// 图片
  119. CachedNetworkImage(imageUrl: model?.jumpImg ?? '', height: 18),
  120. // Container(
  121. // width: 18,
  122. // height: 18,
  123. // color: Colors.red,
  124. // ),
  125. ],
  126. ),
  127. );
  128. }
  129. }
  130. // 上下滚动的消息轮播
  131. class MarqueeWidget extends StatefulWidget {
  132. int count; // 子视图数量
  133. IndexedWidgetBuilder itemBuilder; // 子视图构造器
  134. final ValueChanged<int> onPageChanged;
  135. MarqueeWidget(this.count, this.itemBuilder, {this.onPageChanged});
  136. @override
  137. _MarqueeWidgetState createState() => _MarqueeWidgetState();
  138. }
  139. class _MarqueeWidgetState extends State<MarqueeWidget> {
  140. PageController _controller;
  141. Timer _timer;
  142. @override
  143. void initState() {
  144. super.initState();
  145. if (widget.count > 0) {
  146. _controller = PageController();
  147. _timer = Timer.periodic(Duration(seconds: 5), (timer) {
  148. // 如果当前位于最后一页,则直接跳转到第一页,两者内容相同,跳转时视觉上无感知
  149. try {
  150. if (_controller.page.round() >= widget.count) {
  151. _controller.jumpToPage(0);
  152. }
  153. _controller.nextPage(duration: Duration(seconds: 1), curve: Curves.linear);
  154. } catch (e){
  155. _timer?.cancel();
  156. }
  157. });
  158. }
  159. }
  160. @override
  161. Widget build(BuildContext context) {
  162. // return PageView.builder(
  163. // scrollDirection: Axis.vertical,
  164. // controller: _controller,
  165. // itemBuilder: (buildContext, index) {
  166. // if (index < widget.count) {
  167. // return widget.itemBuilder(buildContext, index);
  168. // } else {
  169. // return widget.itemBuilder(buildContext, 0);
  170. // }
  171. // },
  172. // itemCount: widget.count + 1, // 在原数据末尾添加一笔数据(即第一笔数据),用于实现无限循环滚动效果
  173. // );
  174. // }
  175. return PageView.custom(
  176. physics: NeverScrollableScrollPhysics(),
  177. childrenDelegate: SliverChildBuilderDelegate((context, index) {
  178. if (index < widget.count) {
  179. return widget.itemBuilder(context, index);
  180. } else {
  181. return widget.itemBuilder(context, 0);
  182. }
  183. }, childCount: widget.count + 1),
  184. scrollDirection: Axis.vertical,
  185. controller: _controller,
  186. onPageChanged: widget?.onPageChanged,
  187. );
  188. }
  189. @override
  190. void dispose() {
  191. super.dispose();
  192. _controller?.dispose();
  193. _timer?.cancel();
  194. }
  195. }