import 'package:teso/Classes/API%20Clasess/Desire.dart'; import 'package:flutter/material.dart'; import 'package:jiffy/jiffy.dart'; import 'package:shared_preferences/shared_preferences.dart'; class DesiredItem extends StatefulWidget { final Desire item; final int number; final List selected; const DesiredItem({Key key, this.item, this.number, this.selected}) : super(key: key); @override _DesiredItemState createState() => _DesiredItemState(); } class _DesiredItemState extends State with TickerProviderStateMixin { Animation _spaceWidth; AnimationController _controller; AnimationController _strikeController; Animation _strikePercent; bool cancelled = false; @override void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 150), ); _strikeController = AnimationController( vsync: this, duration: const Duration(milliseconds: 300)); _spaceWidth = Tween(begin: 8, end: 12) .animate(CurvedAnimation(parent: _controller, curve: Curves.easeOut)); _strikePercent = Tween(begin: 0, end: 1).animate( CurvedAnimation(parent: _strikeController, curve: Curves.easeOut)); _spaceWidth.addListener(() { setState(() {}); }); _strikePercent.addListener(() { setState(() {}); }); } cancel() { setState(() { cancelled = !cancelled; }); if (cancelled) { _playAnimation(true); } else { _playAnimation(false); } } Future _playAnimation(bool strikeIn) async { try { if (strikeIn) { _strikeController.forward().orCancel; } else { _strikeController.reverse().orCancel; } await _controller.forward().orCancel; await _controller.reverse().orCancel; } on TickerCanceled { // the animation got canceled, probably because we were disposed } } removeElement(item) { cancel(); if (cancelled) { widget.selected.remove(item); SharedPreferences.getInstance().then((value) { var jiffy = Jiffy()..add(months: 1); value.setString( "desire" + jiffy.format("MMMM, yyyy"), widget.selected.toString()); }); } else { widget.selected.insert(widget.number - 1, item); SharedPreferences.getInstance().then((value) { var jiffy = Jiffy()..add(months: 1); value.setString( "desire" + jiffy.format("MMMM, yyyy"), widget.selected.toString()); }); } } @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), child: IntrinsicHeight( child: Stack( children: [ Row( children: [ SizedBox( width: 40, child: Center( child: Text(widget.number.toString() + ")", style: _getValidateStyle(true)), ), ), Container( width: 1, decoration: BoxDecoration(color: Colors.red), ), SizedBox( width: _spaceWidth.value, ), Padding( padding: const EdgeInsets.all(8.0), child: CustomPaint( foregroundPainter: StrikeThroughPainter(_strikePercent.value), child: Text( widget.item.productName.length > 20 ? widget.item.productName.substring(0, 16) + "......" : widget.item.productName, style: _getValidateStyle(true)), ), ), SizedBox( width: 16, ), ], ), Align( alignment: Alignment.centerRight, child: InkWell( onTap: () => removeElement(widget.item), child: Container( margin: EdgeInsets.only( right: 10, ), width: 22.5, decoration: BoxDecoration( shape: BoxShape.circle, color: cancelled == false ? Colors.red : Colors.green, ), child: Center( child: Text( cancelled == false ? "-" : "+", style: TextStyle(fontSize: 25, color: Colors.white), ), )), ), ) ], ), ), ); } TextStyle _getValidateStyle(bool validation) { return TextStyle( fontWeight: FontWeight.bold, color: (validation) ? Colors.black54 : Colors.black87, fontSize: 18, fontFamily: 'WickedGrit', decoration: null); } } class StrikeThroughPainter extends CustomPainter { StrikeThroughPainter(this.percent); double percent; @override void paint(Canvas canvas, Size size) { canvas.drawRect( Rect.fromLTWH(0, (size.height / 2) - 2, size.width * percent, 4), Paint()..color = Colors.redAccent); } @override bool shouldRepaint(CustomPainter oldDelegate) { return false; } }