coupon_view.dart 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. import 'package:bbyyy/my_tools/event_bus.dart';
  2. import 'package:bbyyy/my_tools/my_colors.dart';
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter_svg/flutter_svg.dart';
  6. class CouponView {
  7. CouponView._internal();
  8. //保存单例
  9. static CouponView _singleton = CouponView._internal();
  10. //工厂构造函数
  11. factory CouponView() => _singleton;
  12. var showIndexs = [];
  13. ticketItem(int index) {
  14. return StatefulBuilder(builder: (BuildContext context,void Function(void Function()) setState){
  15. return Column(
  16. children: [
  17. Container(
  18. height: 124,
  19. margin: EdgeInsets.only(top: 20),
  20. width: double.infinity,
  21. child: ClipShadowPath(
  22. clipper: TicketClipPath(),
  23. shadow: Shadow(blurRadius: 5, color: MyColors.c21333333),
  24. child: Scaffold(
  25. body: Stack(
  26. children: [
  27. Column(
  28. children: [
  29. Padding(
  30. padding:
  31. const EdgeInsets.only(left: 16, top: 9, right: 14),
  32. child: Row(
  33. children: [
  34. Stack(
  35. children: [
  36. Container(
  37. child: SvgPicture.asset(
  38. 'images/svg/优惠券(1).svg',
  39. height: 69,
  40. width: 69,
  41. ),
  42. margin: EdgeInsets.only(right: 12),
  43. ),
  44. Container(
  45. height: 69,
  46. width: 69,
  47. padding: EdgeInsets.only(bottom: 14,left: 16),
  48. child: Row(
  49. children: [
  50. Container(child: Text('¥',style: TextStyle(color: Colors.white,fontSize: 12),),padding: EdgeInsets.only(bottom: 2),),
  51. Text('20',style: TextStyle(color: Colors.white,fontSize: 18),),
  52. ],
  53. crossAxisAlignment: CrossAxisAlignment.end,
  54. ),
  55. ),
  56. ],
  57. ),
  58. Expanded(
  59. child: Column(
  60. children: [
  61. Text(
  62. '满50立减10元券',
  63. style: TextStyle(
  64. color: MyColors.c333333, fontSize: 14),
  65. ),
  66. Container(
  67. margin: EdgeInsets.only(top: 10),
  68. child: Text(
  69. '有效期至2020-08-31 23:59:00',
  70. style: TextStyle(
  71. color: MyColors.c999999,
  72. fontSize: 10),
  73. ),
  74. ),
  75. ],
  76. crossAxisAlignment: CrossAxisAlignment.start,
  77. ),
  78. ),
  79. // Container(
  80. // decoration: BoxDecoration(
  81. // border: Border.all(
  82. // color: MyColors.cFF4233, width: 1),
  83. // borderRadius:
  84. // BorderRadius.all(Radius.circular(11))),
  85. // height: 22,
  86. // width: 58,
  87. // child: Text(
  88. // '立即使用',
  89. // style: TextStyle(
  90. // color: MyColors.cFF4233, fontSize: 11),
  91. // ),
  92. // alignment: Alignment.center,
  93. // padding: EdgeInsets.only(bottom: 2),
  94. // )
  95. ],
  96. ),
  97. ),
  98. Padding(
  99. padding:
  100. EdgeInsets.only(left: 16, right: 15, bottom: 7),
  101. child: Row(
  102. children: [
  103. Container(
  104. height: 18,
  105. width: 46,
  106. decoration: BoxDecoration(
  107. border: Border.all(
  108. color: MyColors.cC6C6C6, width: 0.5),
  109. borderRadius: BorderRadius.all(
  110. Radius.circular(4),
  111. ),
  112. ),
  113. child: Text(
  114. '即将到期',
  115. style: TextStyle(
  116. color: MyColors.c999999, fontSize: 9),
  117. ),
  118. alignment: Alignment.center,
  119. ),
  120. Expanded(
  121. child: GestureDetector(
  122. onTap: (){
  123. if(showIndexs.contains(index)){
  124. showIndexs.remove(index);
  125. }else{
  126. showIndexs.add(index);
  127. }
  128. EventBus().emit('showCouponIndex');
  129. },
  130. behavior: HitTestBehavior.translucent,
  131. child: Container(
  132. padding: EdgeInsets.all(1),
  133. child: Row(
  134. children: [
  135. Text(
  136. '查看详情',
  137. style: TextStyle(
  138. color: MyColors.c999999, fontSize: 11),
  139. ),
  140. Icon(
  141. showIndexs.contains(index)?Icons.arrow_drop_down:Icons.arrow_drop_up,
  142. color: MyColors.c999999,
  143. size: 20,
  144. )
  145. ],
  146. mainAxisAlignment: MainAxisAlignment.end,
  147. ),
  148. ),
  149. ))
  150. ],
  151. ),
  152. )
  153. ],
  154. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  155. ),
  156. Container(
  157. child: CustomPaint(
  158. painter: DashedPainter(),
  159. size: Size(double.infinity, 1),
  160. ),
  161. margin: EdgeInsets.only(
  162. top: 124 / 25 * 18, right: 10, left: 10),
  163. )
  164. ],
  165. ),
  166. ),
  167. ),
  168. ),
  169. AnimatedOpacity(
  170. duration: Duration(milliseconds: 200),
  171. opacity: showIndexs.contains(index)?1:0,
  172. child: Visibility(
  173. visible: showIndexs.contains(index),
  174. child: Container(
  175. width: double.infinity,
  176. height: 114,
  177. margin: EdgeInsets.only( top: 4),
  178. child: ClipShadowPath(
  179. shadow: Shadow(blurRadius: 5, color: MyColors.c21333333),
  180. clipper: DescriptionClipPath(),
  181. child: Scaffold(
  182. body: Column(
  183. children: [
  184. Container(
  185. margin: EdgeInsets.only(top: 16),
  186. child: Text(
  187. '使用规则',
  188. style: TextStyle(color: MyColors.c999999, fontSize: 12),
  189. ),
  190. alignment: Alignment.center,
  191. width: double.infinity,
  192. ),
  193. Container(
  194. margin: EdgeInsets.symmetric(horizontal: 29),
  195. child: Text(
  196. '1.全场商品满50减10元\n2.全部货帮皆可用\n3.仅限梆梆鱼APP使用',
  197. style: TextStyle(color: MyColors.c999999, fontSize: 12),
  198. ),
  199. ),
  200. ],crossAxisAlignment: CrossAxisAlignment.start,
  201. ),
  202. ),
  203. ),
  204. ),
  205. ),
  206. )
  207. ],
  208. );
  209. });
  210. }
  211. }
  212. class TicketClipPath extends CustomClipper<Path> {
  213. @override
  214. Path getClip(Size size) {
  215. print(size);
  216. var path = Path()
  217. ..moveTo(0, 4)
  218. ..quadraticBezierTo(0, 0, 4, 0)
  219. ..lineTo(size.width - 4, 0)
  220. ..quadraticBezierTo(size.width, 0, size.width, 4)
  221. ..lineTo(size.width, size.height / 25 * 18 - 6)
  222. ..quadraticBezierTo(size.width - 6, size.height / 25 * 18 - 6,
  223. size.width - 6, size.height / 25 * 18)
  224. ..quadraticBezierTo(size.width - 6, size.height / 25 * 18 + 6, size.width,
  225. size.height / 25 * 18 + 6)
  226. ..lineTo(size.width, size.height - 4)
  227. ..quadraticBezierTo(size.width, size.height, size.width - 4, size.height)
  228. ..lineTo(4, size.height)
  229. ..quadraticBezierTo(0, size.height, 0, size.height - 4)
  230. ..lineTo(0, size.height / 25 * 18 + 6)
  231. ..quadraticBezierTo(
  232. 6, size.height / 25 * 18 + 6, 6, size.height / 25 * 18)
  233. ..quadraticBezierTo(
  234. 6, size.height / 25 * 18 - 6, 0, size.height / 25 * 18 - 6)
  235. ..close();
  236. return path;
  237. }
  238. @override
  239. bool shouldReclip(CustomClipper<Path> oldClipper) => false;
  240. }
  241. class TicketClipPath2 extends CustomClipper<Path> {
  242. @override
  243. Path getClip(Size size) {
  244. print(size);
  245. var path = Path()
  246. ..moveTo(0, 4)
  247. ..quadraticBezierTo(0, 0, 4, 0)
  248. ..lineTo(size.width - 4, 0)
  249. ..quadraticBezierTo(size.width, 0, size.width, 4)
  250. ..lineTo(size.width, size.height-39 - 6)
  251. ..quadraticBezierTo(size.width - 6, size.height-39 - 6,
  252. size.width - 6, size.height-39)
  253. ..quadraticBezierTo(size.width - 6, size.height-39 + 6, size.width,
  254. size.height-39 + 6)
  255. ..lineTo(size.width, size.height - 4)
  256. ..quadraticBezierTo(size.width, size.height, size.width - 4, size.height)
  257. ..lineTo(4, size.height)
  258. ..quadraticBezierTo(0, size.height, 0, size.height - 4)
  259. ..lineTo(0, size.height-39 + 6)
  260. ..quadraticBezierTo(
  261. 6, size.height-39 + 6, 6, size.height-39)
  262. ..quadraticBezierTo(
  263. 6, size.height-39 - 6, 0, size.height-39 - 6)
  264. ..close();
  265. return path;
  266. }
  267. @override
  268. bool shouldReclip(CustomClipper<Path> oldClipper) => false;
  269. }
  270. class DescriptionClipPath extends CustomClipper<Path> {
  271. @override
  272. Path getClip(Size size) {
  273. double h = size.height;
  274. double w = size.width;
  275. var path = Path()
  276. ..moveTo(0, 10)
  277. ..quadraticBezierTo(0, 6, 4, 6)
  278. ..lineTo(w - 25, 6)
  279. ..lineTo(w - 19, 0)
  280. ..lineTo(w - 13, 6)
  281. ..lineTo(w - 4, 6)
  282. ..quadraticBezierTo(w, 6, w, 10)
  283. ..lineTo(w, h - 4)
  284. ..quadraticBezierTo(w, h, w - 4, h)
  285. ..lineTo(4, h)
  286. ..quadraticBezierTo(0, h, 0, h - 4)
  287. ..close();
  288. return path;
  289. }
  290. @override
  291. bool shouldReclip(CustomClipper<Path> oldClipper) => false;
  292. }
  293. class ClipShadowPath extends StatelessWidget {
  294. final Shadow shadow;
  295. final CustomClipper<Path> clipper;
  296. final Widget child;
  297. ClipShadowPath({
  298. @required this.shadow,
  299. @required this.clipper,
  300. @required this.child,
  301. });
  302. @override
  303. Widget build(BuildContext context) {
  304. return CustomPaint(
  305. key: UniqueKey(),
  306. painter: _ClipShadowShadowPainter(
  307. clipper: this.clipper,
  308. shadow: this.shadow,
  309. ),
  310. child: ClipPath(child: child, clipper: this.clipper),
  311. );
  312. }
  313. }
  314. class _ClipShadowShadowPainter extends CustomPainter {
  315. final Shadow shadow;
  316. final CustomClipper<Path> clipper;
  317. _ClipShadowShadowPainter({@required this.shadow, @required this.clipper});
  318. @override
  319. void paint(Canvas canvas, Size size) {
  320. var paint = shadow.toPaint();
  321. var clipPath = clipper.getClip(size).shift(shadow.offset);
  322. canvas.drawPath(clipPath, paint);
  323. }
  324. @override
  325. bool shouldRepaint(CustomPainter oldDelegate) {
  326. return true;
  327. }
  328. }
  329. class DashedPainter extends CustomPainter {
  330. @override
  331. void paint(Canvas canvas, Size size) {
  332. var paint = Paint() // 创建一个画笔并配置其属性
  333. ..strokeWidth = 1 // 画笔的宽度
  334. ..isAntiAlias = true // 是否抗锯齿
  335. ..color = Color(0xffdbdbdb); // 画笔颜色
  336. var max = size.width; // size获取到宽度
  337. var dashWidth = 5;
  338. var dashSpace = 5;
  339. double startX = 0;
  340. final space = (dashSpace + dashWidth);
  341. while (startX < max) {
  342. canvas.drawLine(
  343. Offset(startX, 0.0), Offset(startX + dashWidth, 0.0), paint);
  344. startX += space;
  345. }
  346. }
  347. @override
  348. bool shouldRepaint(CustomPainter oldDelegate) => false;
  349. }