product card
unknown
dart
2 years ago
14 kB
1
Indexable
Never
import 'package:ease/ease.dart'; import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; class ProductCard extends StatefulWidget { final ImageProvider<Object> image; final String title; final String primarytActionLabel; final String price; final int rate; final VoidCallback? onSubAction; final VoidCallback? onPrimaryAction; final IconData icon; final List? files; final double closedHeight; final double openedHeight; const ProductCard( {Key? key, required this.image, required this.title, required this.primarytActionLabel, required this.price, required this.rate, this.onSubAction, this.onPrimaryAction, this.icon = Icons.favorite_border, this.files, this.closedHeight = 150, this.openedHeight = 300}) : super(key: key); @override _ProductCardState createState() => _ProductCardState(); } class _ProductCardState extends State<ProductCard> with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation _animation; bool isOpened = false; void initState() { super.initState(); _controller = AnimationController(duration: Duration(milliseconds: 375), vsync: this); _animation = Tween(begin: widget.closedHeight, end: widget.openedHeight) .animate(CurvedAnimation( parent: _controller, curve: Curves.easeOut, reverseCurve: Curves.easeOut)); _controller.addListener(() { setState(() {}); }); } @override Widget build(BuildContext context) { return Container( // color: Colors.grey[200], child: Center( child: InkWell( onTap: () { setState(() { isOpened = !isOpened; if (isOpened) { _controller.forward(); } else { _controller.reverse(); } }); }, child: Container( height: _animation.value, // width: 150.0, decoration: BoxDecoration( boxShadow: [ BoxShadow( color: Theme.of(context).shadowColor.withOpacity(.2), blurRadius: 10.0, spreadRadius: 2.0, offset: Offset(0.0, -5.0), ), ], color: Theme.of(context).cardColor, borderRadius: BorderRadius.circular(20.0), ), child: Column( children: [ Container( margin: EdgeInsets.only( top: 10.0, ), height: 130.0, width: 130.0, decoration: BoxDecoration( borderRadius: BorderRadius.circular(15.0), image: DecorationImage( fit: BoxFit.fitWidth, image: widget.image, ), ), ), SizedBox( height: 8, ), widget.files != null ? Flexible( child: AnimatedOpacity( opacity: _animation.value == widget.openedHeight ? 1.0 : 0.0, duration: Duration(milliseconds: 200), child: Container( child: Row( children: List.generate( widget.files!.length, (index) => Card( color: index == 0 ? Colors.red.shade200 : index == 1 ? Colors.orange.shade200 : index == 2 ? Colors.green.shade200 : Colors.indigo.shade200, child: widget.files![index] == null ? Container() : widget.files![index] .contains('pdf') ? InkWell( onTap: () async { if (!await launch( widget.files![index])) throw 'Could not launch $widget.files![index]'; }, child: Txt( " pdf ", color: Colors.white, )) : widget.files![index] .contains('pptx') ? InkWell( onTap: () async { if (!await launch( widget.files![ index])) throw 'Could not launch $widget.files![index]'; }, child: Txt(" pptx ", color: Colors.white)) : widget.files![index] .contains(' ppt ') ? InkWell( onTap: () async { if (!await launch( widget.files![ index])) throw 'Could not launch $widget.files![index]'; }, child: Txt( " ppt ", color: Colors .white)) : InkWell( onTap: () async { if (!await launch( widget.files![ index])) throw 'Could not launch $widget.files![index]'; }, child: Txt( " Video ", color: Colors .white))))), decoration: BoxDecoration( borderRadius: BorderRadius.circular(15.0), color: Colors.white.withOpacity(.1), ), ), ), ) : Container(), Flexible( flex: 3, child: AnimatedOpacity( opacity: _animation.value == widget.openedHeight ? 1.0 : 0.0, duration: Duration(milliseconds: 200), child: Container( child: Column( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Flexible( child: Txt( widget.title, weight: FontWeight.w600, ), ), Flexible( child: Container( padding: EdgeInsets.symmetric(horizontal: 10.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Flexible( flex: 2, child: Text( widget.price, ), ), Flexible( child: Row( children: List.generate( widget.rate, (index) => starIcon( Colors.yellow.shade700)), ), ), ], ), Flexible( child: Container( height: 30.0, width: 30.0, decoration: BoxDecoration( color: Colors.transparent, borderRadius: BorderRadius.circular(12.0), ), child: Material( color: Colors.grey[200], shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.0), ), child: InkWell( onTap: widget.onSubAction, child: Center( child: Icon( widget.icon, size: 15.0, color: Theme.of(context) .primaryColor, ), ), ), ), ), ), ], ), ), ), Flexible( child: Container( margin: EdgeInsets.only(bottom: 0.0), width: 130.0, height: 30.0, decoration: BoxDecoration( color: Colors.blue, borderRadius: BorderRadius.circular(12.0), boxShadow: [ BoxShadow( color: Colors.blue.shade400, offset: Offset(0.0, 10.0), spreadRadius: -5.0, blurRadius: 10.0, ), ], ), child: Material( color: Colors.transparent, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.0), ), child: InkWell( onTap: widget.onPrimaryAction, child: Center( child: Text( widget.primarytActionLabel, style: TextStyle(color: Colors.white), ), ), ), ), ), ), ], ), ), ), ) ], ), ), ), ), ); } Icon starIcon(Color color) { return Icon( Icons.star, size: 10.0, color: color, ); } }