Product card
On this page
The Flutter Helpers are available as alpha software. They depend on the Algolia Dart API client, which is developed by the community. Note that the Algolia SLA don’t apply to community projects. To share feedback or report a bug, open an issue.
The Product view components allow you to show your product data from an Algolia index as a product card. Use:
- The
ProductCardView
widget to display product information in a list or grid. - The
ProductItemView
widget to display product information with details in a list.
Product card
The ProductCardView
component lets you display product information. For example, you can show product cards in a list or grid view.
Code summary
You can customize ProductCardView
in:
Usage and props
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
class ProductCardView extends StatelessWidget {
const ProductCardView(
{Key? key,
required this.product,
this.imageAlignment = Alignment.bottomCenter,
this.onTap})
: super(key: key);
final Product product;
final Alignment imageAlignment;
final Function(String)? onTap;
@override
Widget build(BuildContext context) {
final priceValue = (product.price?.onSales ?? false)
? product.price?.discountedValue
: product.price?.value;
final crossedValue =
(product.price?.onSales ?? false) ? product.price?.value : null;
return GestureDetector(
onTap: () => onTap?.call(product.objectID!),
child: SizedBox(
width: 150,
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Stack(
alignment: AlignmentDirectional.bottomStart,
children: [
SizedBox(
height: 100,
width: MediaQuery.of(context).size.width,
child: Image.network('${product.image}',
alignment: imageAlignment, fit: BoxFit.cover)),
if (product.price?.onSales == true)
Padding(
padding: const EdgeInsets.all(4.0),
child: Text(" ON SALE ${product.price?.discountLevel}% ",
style: Theme.of(context).textTheme.caption?.copyWith(
color: Colors.white,
backgroundColor: AppTheme.darkPink)),
)
],
),
const SizedBox(height: 8),
SizedBox(
child: Text('${product.brand}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
softWrap: false,
style: Theme.of(context).textTheme.caption)),
SizedBox(
child: Text('${product.name}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
softWrap: false,
style: Theme.of(context).textTheme.bodyText2)),
Padding(
padding: const EdgeInsets.symmetric(vertical: 2.0),
child: ColorIndicatorView(product: product),
),
Row(
children: [
Text('$priceValue €',
maxLines: 1,
overflow: TextOverflow.clip,
softWrap: false,
style: Theme.of(context).textTheme.bodyText2?.copyWith(
fontWeight: FontWeight.bold,
color: AppTheme.vividOrange)),
if (crossedValue != null)
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text('$crossedValue €',
maxLines: 1,
overflow: TextOverflow.clip,
softWrap: false,
style: Theme.of(context)
.textTheme
.caption
?.copyWith(decoration: TextDecoration.lineThrough)),
),
],
),
RatingView(
value: product.reviews?.rating?.toInt() ?? 0,
reviewsCount: product.reviews?.count?.toInt() ?? 0),
]),
),
);
}
}
Product item
The ProductItemView
component lets you display product information. For example, you can show product item with details in a list.
Code summary
You can customize ProductItemView
in:
Usage and props
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
class ProductItemView extends StatelessWidget {
const ProductItemView(
{Key? key,
required this.product,
this.imageAlignment = Alignment.center,
this.onProductPressed})
: super(key: key);
final Product product;
final Alignment imageAlignment;
final Function(String)? onProductPressed;
@override
Widget build(BuildContext context) {
final priceValue = (product.price?.onSales ?? false)
? product.price?.discountedValue
: product.price?.value;
final crossedValue =
(product.price?.onSales ?? false) ? product.price?.value : null;
return GestureDetector(
onTap: () {
onProductPressed?.call(product.objectID!);
},
child: SizedBox(
child: Row(mainAxisSize: MainAxisSize.min, children: [
Stack(
alignment: AlignmentDirectional.bottomStart,
children: [
SizedBox(
height: 100,
width: 100,
child: Image.network('${product.image}',
alignment: imageAlignment, fit: BoxFit.cover)),
if (product.price?.onSales == true)
Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
" ON SALE ${product.price?.discountLevel}% ",
style: Theme.of(context).textTheme.caption?.copyWith(
color: Colors.white,
backgroundColor: AppTheme.darkPink),
))
],
),
const SizedBox(width: 8),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('${product.brand}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
softWrap: false,
style: Theme.of(context).textTheme.caption),
Text('${product.name}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
softWrap: false,
style: Theme.of(context).textTheme.bodyText1),
if (product.description?.isNotEmpty == true)
Text('${product.description}',
maxLines: 2,
overflow: TextOverflow.ellipsis,
softWrap: false,
style: Theme.of(context)
.textTheme
.bodyText2
?.copyWith(fontSize: 12, color: Colors.grey)),
Padding(
padding: const EdgeInsets.symmetric(vertical: 2.0),
child: ColorIndicatorView(product: product),
),
Row(
children: [
Text('$priceValue €',
maxLines: 1,
overflow: TextOverflow.clip,
softWrap: false,
style: Theme.of(context).textTheme.bodyText2?.copyWith(
fontWeight: FontWeight.bold,
color: AppTheme.vividOrange)),
if (crossedValue != null)
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Text('$crossedValue €',
maxLines: 1,
overflow: TextOverflow.clip,
softWrap: false,
style: Theme.of(context)
.textTheme
.caption
?.copyWith(
decoration: TextDecoration.lineThrough)),
),
],
),
RatingView(
value: product.reviews?.rating?.toInt() ?? 0,
reviewsCount: product.reviews?.count?.toInt() ?? 0),
],
),
),
]),
),
);
}
}