import 'dart:async'; import 'package:fast/constants.dart'; import 'package:fast/extension/relation.dart'; import 'package:fast/model/model.dart'; import 'package:fast/utils/api.dart'; import 'package:fast/utils/global.dart'; import 'package:fast/utils/http_utils.dart'; import 'package:fast/utils/size_fit.dart'; import 'package:fast/utils/util.dart'; import 'package:fast/view/component/navi_bar.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'component/calendar_item.dart'; import 'component/loading.dart'; GlobalKey selKey = GlobalKey(); // ignore: must_be_immutable class CalendarDetail extends StatefulWidget { List calendarList; int selDay, selMonth, selYear; CalendarDetail( {Key? key, required this.calendarList, required this.selYear, required this.selMonth, required this.selDay}) : super(key: key); @override State createState() => _CalendarDetailState(); } class _CalendarDetailState extends State { late ScrollController controller; late List calendars; bool isLoading = true; double top = 0.0; @override void initState() { controller = ScrollController(); calendars = []; // Timer(const Duration(milliseconds: 500), () { // final RenderBox widget = // selKey.currentContext!.findRenderObject() as RenderBox; // var offset = widget.localToGlobal(Offset.zero); // controller.animateTo(offset.dy - top - 40.px, // duration: const Duration(milliseconds: 400), curve: Curves.linear); // // controller.jumpTo(offset.dy); // var size = 0; // }); getRecords(); super.initState(); } @override void dispose() { controller.dispose(); super.dispose(); } DateTime serverTime() { int milliseconds = DateTime.now().millisecondsSinceEpoch; milliseconds = milliseconds + Global().timeSeconds * 1000; return DateTime.fromMillisecondsSinceEpoch(milliseconds); } Future getRecords() async { Map data = await HttpUtils.get(Api.records, params: {"day_begin": "20220101", "day_end": "20221212"}); initCalendar(data); Timer(const Duration(seconds: 1), () { setState(() { isLoading = false; }); }); } initCalendar(data) { List list = []; for (int i = 0; i < widget.calendarList.length; i++) { List array = widget.calendarList[i]; for (var e in array) { if (e.day != null) { list.add(e); } } } //贴纸 for (int i = 0; i < data['records'].length; i++) { var fastObj = data['records'][i]; if (fastObj['mode'] == 'CHALLENGER' && (fastObj['status'] == 'DOING' || fastObj['status'] == 'END' || fastObj['status'] == 'TIMEOUT' || fastObj['status'] == 'EXIT') && fastObj['checkin_days'].length > 0) { int startTime = fastObj['checkin_days'][0]['start_time']; int endTime = fastObj['checkin_days'] [fastObj['checkin_days'].length - 1]['end_time']; for (CalendarItemBean bean in list) { int? year = bean.year; int? month = bean.month; int? day = bean.day; int startTimeStamp = DateTime(year!, month!, day!).millisecondsSinceEpoch ~/ 1000; int endTimeStamp = startTimeStamp + 24 * 3600; double startPercent = 0.0; double widthPercent = 0.0; if ((startTimeStamp < startTime && endTimeStamp < startTime) || (startTimeStamp > endTime && endTimeStamp > endTime)) { } else { if (startTimeStamp < startTime) { startPercent = (startTime - startTimeStamp) / (24 * 3600); if (endTimeStamp < endTime) { widthPercent = (endTimeStamp - startTime) / (24 * 3600); } else { widthPercent = (endTime - startTime) / (24 * 3600); } } else { if (endTimeStamp <= endTime) { widthPercent = 1.0; } else { widthPercent = (endTime - startTimeStamp) / (24 * 3600); } } RecordSticker sticker = RecordSticker(); sticker.begin = startPercent; sticker.width = widthPercent; sticker.days = fastObj['days']; if (bean.recordItem == null) { RecordItem item = RecordItem(); bean.recordItem = item; } if (bean.recordItem!.stickers == null) { List stickers = []; bean.recordItem!.stickers = stickers; } bean.recordItem!.stickers!.add(sticker); } } } } //正在进行的进度条背景 if (data['records'].length > 0 && data['records'][data['records'].length - 1]['status'] == 'DOING') { List array; if (data['records'][data['records'].length - 1]['mode'] == 'SINGLE') { var singleObj = data['records'][data['records'].length - 1]; array = [ { "day_num": singleObj['begin_day_num'], "start_time": singleObj['start_time'], "end_time": singleObj['end_time'], "cross_day": singleObj['cross_day'] } ]; } else { array = data['records'][data['records'].length - 1]['checkin_days']; } for (var obj in array) { int year = Util().getYearFromTimenum(obj['day_num']); int month = Util().getMonthFromTimenum(obj['day_num']); int day = Util().getDayFromTimenum(obj['day_num']); int time = DateTime(year, month, day).millisecondsSinceEpoch ~/ 1000; DateTime dateTime = DateTime(year, month, day + 1); int year1 = dateTime.year; int month1 = dateTime.month; int day1 = dateTime.day; int time1 = dateTime.millisecondsSinceEpoch ~/ 1000; double beginProgress = (obj['start_time'] - time) / (24 * 3600); double widthProgress = (obj['end_time'] - obj['start_time']) / (24 * 3600); double beginProgress2 = 0.0; double widthProgress2 = 0.0; if (obj['cross_day']) { widthProgress = 1.0 - beginProgress; widthProgress2 = (obj['end_time'] - time1) / (24 * 3600); } int now = DateTime.now().millisecondsSinceEpoch ~/ 1000; bool foundCurrent = false; if (obj['start_time'] <= now && now <= obj['end_time']) { foundCurrent = true; } for (CalendarItemBean bean in list) { bean.recordItem ??= RecordItem(); if (bean.recordItem!.progressBg == null) { bean.recordItem!.progressBg = []; } if (bean.year == year && bean.month == month && bean.day == day) { double percent = (now - obj['start_time']) / (obj['end_time'] - obj['start_time']); RecordProgress? currentProgress; if (foundCurrent && widthProgress / (widthProgress + widthProgress2) >= percent) { currentProgress = RecordProgress(); currentProgress.beginAlpha = 0.0; currentProgress.endAlpha = 1.0; currentProgress.width = percent * (widthProgress + widthProgress2) / widthProgress; currentProgress.showArrow = true; } else if (foundCurrent) { currentProgress = RecordProgress(); currentProgress.beginAlpha = 0.0; currentProgress.endAlpha = widthProgress / ((widthProgress + widthProgress2) * percent); currentProgress.width = 1.0; currentProgress.showArrow = false; } RecordProgressBg recordProgressBg = RecordProgressBg(); if (currentProgress != null) { recordProgressBg.progress = currentProgress; } recordProgressBg.showStart = foundCurrent; recordProgressBg.showTarget = (obj['cross_day'] || !foundCurrent) ? false : true; recordProgressBg.begin = beginProgress; recordProgressBg.width = widthProgress; bean.recordItem!.progressBg!.add(recordProgressBg); } if (obj['cross_day'] && bean.year == year1 && bean.month == month1 && bean.day == day1) { double percent = (now - obj['start_time']) / (obj['end_time'] - obj['start_time']); RecordProgress? currentProgress; if (foundCurrent && widthProgress / (widthProgress + widthProgress2) < percent) { currentProgress = RecordProgress(); currentProgress.beginAlpha = widthProgress / ((widthProgress + widthProgress2) * percent); currentProgress.endAlpha = 1.0; currentProgress.width = ((widthProgress + widthProgress2) * percent - widthProgress) / widthProgress2; currentProgress.showArrow = true; } RecordProgressBg recordProgressBg = RecordProgressBg(); if (currentProgress != null) { recordProgressBg.progress = currentProgress; } recordProgressBg.showStart = false; recordProgressBg.showTarget = foundCurrent ? true : false; recordProgressBg.begin = beginProgress2; recordProgressBg.width = widthProgress2; bean.recordItem!.progressBg!.add(recordProgressBg); } } } } //完成的进度 for (int i = 0; i < data['records'].length; i++) { var fastObj = data['records'][i]; if (fastObj['mode'] == 'SINGLE' && fastObj['status'] != 'DOING') { setProgressData(list, fastObj['cross_day'], fastObj['start_time'], fastObj['real_end_time'], fastObj['begin_day_num']); continue; } if (fastObj['mode'] == 'SINGLE') { continue; } List array = fastObj['checkin_days']; for (var obj in array) { if ((obj['checkout_status'] != 'SUCCESS' && obj['checkout_status'] != 'TIMEOUT') && fastObj['status'] == 'DOING') { continue; } setProgressData(list, obj['cross_day'], obj['start_time'], obj['end_time'], obj['day_num']); } } if (data['records'].length > 0 && data['records'][data['records'].length - 1]['status'] == 'DOING' && data['records'][data['records'].length - 1]['mode'] == 'SINGLE') { var singleObj = data['records'][data['records'].length - 1]; int now = serverTime().millisecondsSinceEpoch ~/ 1000; num duration = now - singleObj['start_time']; int year = Util().getYearFromTimenum(singleObj['begin_day_num']); int month = Util().getMonthFromTimenum(singleObj['begin_day_num']); int day = Util().getDayFromTimenum(singleObj['begin_day_num']); DateTime beginDate = DateTime(year, month, day); int firstEndTimestamp = beginDate.millisecondsSinceEpoch ~/ 1000 + 3600 * 24; var array = []; double tempAlpha = 0.0; num width = firstEndTimestamp - singleObj['start_time'] > duration ? duration : (firstEndTimestamp - singleObj['start_time']); tempAlpha = width / duration; var obj = { 'beginAlpha': 0.0, 'endAlpha': tempAlpha, 'begin': (3600 * 24 - firstEndTimestamp + singleObj['start_time']) / (3600 * 24), 'width': width / (3600 * 24), 'date': DateTime.now(), 'showArrow': false }; array.add(obj); if (firstEndTimestamp - singleObj['start_time'] < duration) { int temp = firstEndTimestamp; while (temp + 24 * 3600 <= now) { var obj2 = { 'begin': 0.0, 'width': 1.0, 'beginAlpha': tempAlpha, 'endAlpha': tempAlpha + 24 * 3600 / duration, 'showArrow': false, 'date': DateTime.now() }; tempAlpha += 24 * 3600 / duration; array.add(obj2); if (temp + 24 * 3600 > now) { break; } temp = temp + 24 * 3600; } if (temp < now) { var obj3 = { 'begin': 0.0, 'width': (now - temp) / (24 * 3600), 'beginAlpha': tempAlpha, 'showArrow': false, 'date': DateTime.now() }; array.add(obj3); } } array[array.length - 1]['endAlpha'] = 1.0; array[array.length - 1]['showArrow'] = true; for (int i = 0; i < array.length; i++) { array[i]['date'] = DateTime(beginDate.year, beginDate.month, beginDate.day + i); } list.forEach((monthObj) { array.forEach((obj) { DateTime dt = obj['date']; if (monthObj.year == dt.year && monthObj.month == dt.month && monthObj.day == dt.day) { monthObj.isHighlight = true; monthObj.singleProgress = obj; } }); }); // list.map((CalendarItemBean monthObj) => { // int ss = monthObj.year! // int month0 = monthObj.month!; // }); } setState(() { calendars = list; }); Timer(const Duration(milliseconds: 500), () { final RenderBox widget = selKey.currentContext!.findRenderObject() as RenderBox; var offset = widget.localToGlobal(Offset.zero); controller.animateTo(offset.dy - top - 40.px - 100.px, duration: const Duration(milliseconds: 400), curve: Curves.linear); // controller.jumpTo(offset.dy); // var size = 0; }); } void setProgressData(List list, bool crossDay, int startTime, int endTime, int dayNum) { if (startTime >= endTime) { return; } int year = Util().getYearFromTimenum(dayNum); int month = Util().getMonthFromTimenum(dayNum); int day = Util().getDayFromTimenum(dayNum); int time = DateTime(year, month, day).millisecondsSinceEpoch ~/ 1000; DateTime dateTime = DateTime(year, month, day + 1); int year1 = dateTime.year; int month1 = dateTime.month; int day1 = dateTime.day; int time1 = dateTime.millisecondsSinceEpoch ~/ 1000; double beginProgress = (startTime - time) / (24 * 3600); double widthProgress = (endTime - startTime) / (24 * 3600); double beginProgress2 = 0.0; double widthProgress2 = 0.0; if (crossDay) { widthProgress = 1.0 - beginProgress; widthProgress2 = (endTime - time1) / (24 * 3600) < 0 ? 0 : (endTime - time1) / (24 * 3600); } for (CalendarItemBean bean in list) { bean.recordItem ??= RecordItem(); if (bean.recordItem!.progress == null) { bean.recordItem!.progress = []; } if (bean.year == year && bean.month == month && bean.day == day) { RecordProgress progress = RecordProgress(); progress.width = widthProgress; progress.begin = beginProgress; bean.recordItem!.progress!.add(progress); } if (crossDay && bean.year == year1 && bean.month == month1 && bean.day == day1) { RecordProgress progress = RecordProgress(); progress.width = widthProgress2; progress.begin = beginProgress2; bean.recordItem!.progress!.add(progress); } } } @override Widget build(BuildContext context) { EdgeInsets safePadding = MediaQuery.of(context).padding; top = safePadding.top; return Material( child: Container( color: kBgColor, child: Stack( children: [ Opacity( opacity: isLoading ? 0.0 : 1.0, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: SingleChildScrollView( controller: controller, child: Container( margin: EdgeInsets.only(top: 40.px + top + 60.px), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: List.generate(calendars.length, (i) { return Opacity( opacity: (calendars[i].isHighlight || calendars[i].isToday) ? 1.0 : 0.5, child: recordItem(calendars[i]), ); })), ), )) ], ), ), // if (isLoading) // Expanded( // child: Container( // alignment: Alignment.center, // margin: EdgeInsets.only(bottom: 20.px), // color: Colors.pink, // child: SizedBox( // child: Loading(), // width: 144.px, // height: 150.px, // ))), NaviBar( title: '记录详情', closeCallback: () { Get.back(); }, showBar: true, ), ], ), ), ); } recordItem(CalendarItemBean bean) { return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ if (bean.month == 1) Container( margin: EdgeInsets.only(bottom: 8.px), child: Text( bean.year.toString(), style: TextStyle( color: const Color(0x66FFFFFF), fontSize: 24.px, fontFamily: 'Exo2', height: 1, fontWeight: FontWeight.w900), ), ), if (bean.day == 1) Container( margin: EdgeInsets.only(left: 16.px,right: 16.px,top: 16.px), child: Row( children: [ Text( '${bean.month}月', style: TextStyle( fontWeight: FontWeight.bold, color: const Color(0x66C4CCDA), fontFamily: 'Exo2', height: 1.0, fontSize: 20.px), ), Expanded( child: Container( height: 1.px, margin: EdgeInsets.only(left: 12.px), // width: 297.px, color: const Color(0x1AFFFFFF), )) ], ), ), Stack( children: [ Container( alignment: Alignment.centerLeft, margin: EdgeInsets.only( top: bean.isToday ? 5.px : 0, bottom: bean.isToday ? 5.px : 0, left: 17.px), child: CalendarItem( bean: bean, key: (bean.year == widget.selYear && bean.month == widget.selMonth && bean.day == widget.selDay) ? selKey : GlobalKey(), ), ), if (bean.recordItem != null && bean.recordItem!.progressBg != null) ...List.generate(bean.recordItem!.progressBg!.length, (i) { return progressTargetItem(bean.recordItem!, i); }) ], ), Stack( children: [ Container( margin: EdgeInsets.only(left: 16.px, right: 16.px), child: ClipRRect( borderRadius: BorderRadius.all(Radius.circular(14.px)), child: Container( width: 343.px, height: 28.px, decoration: BoxDecoration( color: const Color(0x14C4CCDA), borderRadius: BorderRadius.all(Radius.circular(14.px))), child: Stack( children: [ if (bean.recordItem != null && bean.recordItem!.progressBg != null) Stack( children: List.generate( bean.recordItem!.progressBg!.length, (i) { return progressBgItem(bean.recordItem!, i); })), if (bean.recordItem != null && bean.recordItem!.progress != null && bean.recordItem!.progress!.isNotEmpty) Stack( children: List.generate( bean.recordItem!.progress!.length, (i) { return progressItem(bean.recordItem!, i); })), if (bean.singleProgress != null) Container( margin: EdgeInsets.only( left: bean.singleProgress['begin'] * 343.px), width: bean.singleProgress['width'] * 343.px, // (bean.singleProgress['width'] * 343.px < 28.px && // bean.singleProgress['showArrow']) // ? 28.px // : bean.singleProgress['width'] * 343.px, decoration: BoxDecoration( // color: kThemeColor, gradient: LinearGradient( begin: Alignment.centerLeft, end: Alignment.centerRight, colors: [ Color.fromARGB( (bean.singleProgress['beginAlpha'] * 255) .toInt(), 175, 255, 0), Color.fromARGB( (bean.singleProgress['endAlpha'] * 255) .toInt(), 175, 255, 0) ]), // borderRadius: // BorderRadius.all(Radius.circular(14.px)) ), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.end, children: [ bean.singleProgress['showArrow'] && bean.singleProgress['width'] * 343.px >= 28.px ? Image.asset( 'assets/images/arrow_foward.png', width: 28.px, height: 28.px, ) : SizedBox( width: 1.px, height: 28.px, ) ], ), ) ], )), ), ), // Container( // margin: EdgeInsets.only(left: 16.px, right: 16.px), // width: 343.px, // height: 28.px, // child: Stack(children: [ // if (bean.recordItem != null && // bean.recordItem!.progressBg != null) // Stack( // children: List.generate( // bean.recordItem!.progressBg!.length, (i) { // return progressTargetItem(bean.recordItem!, i); // })) // ])) ], ), // Container( // margin: EdgeInsets.only(left: 16.px, right: 16.px), // width: 343.px, // height: 28.px, // decoration: BoxDecoration( // color: const Color(0x14C4CCDA), // borderRadius: BorderRadius.all(Radius.circular(14.px))), // child: Stack( // children: [ // if (bean.recordItem != null && // bean.recordItem!.progressBg != null) // Stack( // children: List.generate( // bean.recordItem!.progressBg!.length, (i) { // return progressBgItem(bean.recordItem!, i); // })), // if (bean.recordItem != null && // bean.recordItem!.progress != null && // bean.recordItem!.progress!.isNotEmpty) // Stack( // children: List.generate( // bean.recordItem!.progress!.length, (i) { // return progressItem(bean.recordItem!, i); // })), // if (bean.singleProgress != null) // Container( // margin: EdgeInsets.only( // left: bean.singleProgress['begin'] * 343.px), // width: (bean.singleProgress['width'] * 343.px < 28.px && // bean.singleProgress['showArrow']) // ? 28.px // : bean.singleProgress['width'] * 343.px, // decoration: BoxDecoration( // // color: kThemeColor, // gradient: LinearGradient( // begin: Alignment.centerLeft, // end: Alignment.centerRight, // colors: [ // Color.fromARGB( // (bean.singleProgress['beginAlpha'] * 255) // .toInt(), // 175, // 255, // 0), // Color.fromARGB( // (bean.singleProgress['endAlpha'] * 255).toInt(), // 175, // 255, // 0) // ]), // borderRadius: BorderRadius.all(Radius.circular(14.px))), // child: Row( // mainAxisSize: MainAxisSize.max, // mainAxisAlignment: MainAxisAlignment.end, // children: [ // bean.singleProgress['showArrow'] // ? Image.asset( // 'assets/images/arrow_foward.png', // width: 28.px, // height: 28.px, // ) // : SizedBox( // width: 1.px, // height: 28.px, // ) // ], // ), // ) // ], // )), SizedBox( height: 10.px, ), if (bean.recordItem != null && bean.recordItem!.stickers != null) Stack( children: List.generate(bean.recordItem!.stickers!.length, (i) { return stickerItem(bean.recordItem!, i); }), ), ]); } progressTargetItem(RecordItem item, int i) { List? list = item.progressBg; RecordProgressBg progressBg = list![i]; return Positioned( bottom: 0, child: SizedBox( width: 375.px, height: 50.px, child: Stack( children: [ if (progressBg.showStart != null && progressBg.showStart == true) Positioned( left: progressBg.begin * 343.px, bottom: 0, child: Image.asset( 'assets/images/calendar_detail_begin.png', width: 32.px, height: 40.px, ), ), if (progressBg.showTarget != null && progressBg.showTarget == true) Positioned( left: progressBg.begin * 343.px+343.px * progressBg.width, bottom: 0, child: Image.asset( 'assets/images/calendar_detail_end.png', width: 32.px, height: 40.px, ), ) ], ), )); /* return Container( margin: EdgeInsets.only(left: progressBg.begin * 343.px), width: 343.px * progressBg.width, height: 40.px, child: Stack( children: [ if (progressBg.showStart != null && progressBg.showStart == true) Container( margin: EdgeInsets.zero, width: 0, height: 0, ).relationOne( -16.px, -28.px, Image.asset( 'assets/images/calendar_detail_begin.png', width: 32.px, height: 40.px, )), if (progressBg.showTarget != null && progressBg.showTarget == true) Positioned( left: 343.px * progressBg.width, child: Container( margin: EdgeInsets.zero, width: 0, height: 0, )).relationOne( 343.px * progressBg.width - 16.px, -28.px, Image.asset( 'assets/images/calendar_detail_end.png', width: 32.px, height: 40.px, )), ], ), );*/ /* List? list = item.progressBg; RecordProgressBg progressBg = list![i]; return Container( margin: EdgeInsets.only(left: progressBg.begin * 343.px), width: 343.px * progressBg.width, height: 28.px, child: Stack( children: [ if (progressBg.showStart != null && progressBg.showStart == true) Container( margin: EdgeInsets.zero, width: 0, height: 0, ).relationOne( -16.px, -28.px, Image.asset( 'assets/images/calendar_detail_begin.png', width: 32.px, height: 40.px, )), if (progressBg.showTarget != null && progressBg.showTarget == true) Positioned( left: 343.px * progressBg.width, child: Container( margin: EdgeInsets.zero, width: 0, height: 0, )).relationOne( 343.px * progressBg.width - 16.px, -28.px, Image.asset( 'assets/images/calendar_detail_end.png', width: 32.px, height: 40.px, )), ], ), );*/ } progressBgItem(RecordItem item, int i) { List? list = item.progressBg; RecordProgressBg progressBg = list![i]; return Container( margin: EdgeInsets.only(left: progressBg.begin * 343.px), width: 343.px * progressBg.width, height: 28.px, decoration: const BoxDecoration( color: Color(0x26C4CCDA), // borderRadius: BorderRadius.all(Radius.circular(14.px)) ), child: Stack( children: [ if (progressBg.showStart != null && progressBg.showStart == true) Container( margin: EdgeInsets.zero, width: 0, height: 0, ).relationOne( -16.px, -28.px, Image.asset( 'assets/images/calendar_detail_begin.png', width: 32.px, height: 40.px, )), if (progressBg.showTarget != null && progressBg.showTarget == true) Positioned( left: 343.px * progressBg.width, child: Container( margin: EdgeInsets.zero, width: 0, height: 0, )).relationOne( 343.px * progressBg.width - 16.px, -28.px, Image.asset( 'assets/images/calendar_detail_end.png', width: 32.px, height: 40.px, )), // if (progressBg.progress != null) // Container( // width: // 343.px * progressBg.width * progressBg.progress!.width < 28.px // ? 28.px // : 343.px * progressBg.width * progressBg.progress!.width, // height: 28.px, // alignment: Alignment.centerRight, // decoration:const BoxDecoration( // image: DecorationImage( // image: AssetImage('assets/images/arrow_foward.png'), // scale: 0.8, // alignment: Alignment.centerRight)), // ) ], ), ); } progressItem(RecordItem item, int i) { List? list = item.progress; RecordProgress progress = list![i]; if (progress.width < 0) { progress.width = 0.0; } return Container( margin: EdgeInsets.only(left: 343.px * progress.begin), width: 343.px * progress.width, height: 28.px, alignment: Alignment.centerRight, decoration: const BoxDecoration( color: kThemeColor, // borderRadius: BorderRadius.all(Radius.circular(14.px)), )); } stickerItem(RecordItem item, int i) { List? list = item.stickers; RecordSticker sticker = list![i]; return Container( alignment: Alignment.centerLeft, width: 343.px * sticker.width, height: 12.px, margin: EdgeInsets.only(left: 16.px + 343.px * sticker.begin), decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(6.px)), image: DecorationImage( image: AssetImage('assets/images/${sticker.days}_progress.png'), alignment: sticker.begin == 0.0 ? Alignment.centerLeft : Alignment.centerRight, fit: BoxFit.cover)), ); } }