Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5599c53

Browse files
Add slidable remove item to cart page
1 parent f5ea1c1 commit 5599c53

File tree

2 files changed

+100
-68
lines changed

2 files changed

+100
-68
lines changed

‎lib/pages/cart.dart

Lines changed: 98 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:day34/pages/product_view.dart';
66
import 'package:dotted_border/dotted_border.dart';
77
import 'package:flutter/material.dart';
88
import 'package:flutter/services.dart';
9+
import 'package:flutter_slidable/flutter_slidable.dart';
910

1011
class CartPage extends StatefulWidget {
1112
const CartPage({ Key? key }) : super(key: key);
@@ -14,21 +15,19 @@ class CartPage extends StatefulWidget {
1415
_CartPageState createState() => _CartPageState();
1516
}
1617

17-
class _CartPageState extends State<CartPage> {
18-
List<dynamic> cartItems = [];
18+
class _CartPageState extends State<CartPage> withTickerProviderStateMixin{
19+
lateList<dynamic> cartItems = [];
1920
List<int> cartItemCount = [1, 1, 1, 1];
2021
int totalPrice = 0;
2122

2223
Future<void> fetchItems() async {
2324
final String response = await rootBundle.loadString('assets/products.json');
2425
final data = await json.decode(response);
2526

26-
setState(() {
27-
cartItems = data['products']
28-
.map((data) => Product.fromJson(data)).toList();
29-
30-
sumTotal();
31-
});
27+
cartItems = data['products']
28+
.map((data) => Product.fromJson(data)).toList();
29+
30+
sumTotal();
3231
}
3332

3433
sumTotal() {
@@ -40,8 +39,9 @@ class _CartPageState extends State<CartPage> {
4039
@override
4140
void initState() {
4241
// TODO: implement initState
43-
fetchItems();
4442
super.initState();
43+
44+
fetchItems().whenComplete(() => setState(() {}));
4545
}
4646

4747
@override
@@ -52,82 +52,112 @@ class _CartPageState extends State<CartPage> {
5252
backgroundColor: Colors.transparent,
5353
title: Text('My Cart', style: TextStyle(color: Colors.black)),
5454
),
55-
body: SingleChildScrollView(
56-
child: Column(
57-
children: <Widget>[
58-
Container(
59-
padding: EdgeInsets.symmetric(horizontal: 20),
60-
height: MediaQuery.of(context).size.height * 0.53,
61-
child: ListView.builder(
55+
body: Column(
56+
crossAxisAlignment: CrossAxisAlignment.start,
57+
children: <Widget>[
58+
Container(
59+
padding: EdgeInsets.symmetric(horizontal: 20),
60+
height: MediaQuery.of(context).size.height * 0.53,
61+
child: cartItems.length > 0 ? FadeAnimation(1.4,
62+
AnimatedList(
6263
scrollDirection: Axis.vertical,
63-
itemCount: cartItems.length,
64-
itemBuilder: (context, index) {
65-
return cartItem(cartItems[index], index);
64+
initialItemCount: cartItems.length,
65+
itemBuilder: (context, index, animation) {
66+
return Slidable(
67+
actionPane: SlidableDrawerActionPane(),
68+
secondaryActions: [
69+
MaterialButton(
70+
color: Colors.red.withOpacity(0.15),
71+
elevation: 0,
72+
height: 60,
73+
minWidth: 60,
74+
shape: CircleBorder(),
75+
child: Icon(Icons.delete, color: Colors.red, size: 30,),
76+
onPressed: () {
77+
setState(() {
78+
totalPrice = totalPrice - (int.parse(cartItems[index].price.toString()) * cartItemCount[index]);
79+
80+
AnimatedList.of(context).removeItem(index, (context, animation) {
81+
return cartItem(cartItems[index], index, animation);
82+
});
83+
84+
cartItems.removeAt(index);
85+
cartItemCount.removeAt(index);
86+
});
87+
},
88+
),
89+
],
90+
child: cartItem(cartItems[index], index, animation),
91+
);
6692
}
6793
),
68-
),
69-
SizedBox(height: 30),
70-
FadeAnimation(1.2,
71-
Container(
72-
padding: EdgeInsets.symmetric(horizontal: 20),
73-
child: Row(
74-
mainAxisAlignment: MainAxisAlignment.spaceBetween,
75-
children: <Widget>[
76-
Text('Shipping', style: TextStyle(fontSize: 20)),
77-
Text('\$5.99', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold))
78-
],
79-
),
80-
),
81-
),
82-
FadeAnimation(1.3, Padding(
83-
padding: EdgeInsets.all(20.0),
84-
child: DottedBorder(
85-
color: Colors.grey.shade400,
86-
dashPattern: [10, 10],
87-
padding: EdgeInsets.all(0),
88-
child: Container()
89-
),
90-
)),
91-
FadeAnimation(1.3, Container(
94+
) : Container(),
95+
),
96+
SizedBox(height: 30),
97+
FadeAnimation(1.2,
98+
Container(
9299
padding: EdgeInsets.symmetric(horizontal: 20),
93100
child: Row(
94101
mainAxisAlignment: MainAxisAlignment.spaceBetween,
95102
children: <Widget>[
96-
Text('Total', style: TextStyle(fontSize: 20)),
97-
Text('\$${totalPrice + 5.99}', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold))
103+
Text('Shipping', style: TextStyle(fontSize: 20)),
104+
Text('\$5.99', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold))
98105
],
99106
),
100-
)),
101-
SizedBox(height: 10),
102-
FadeAnimation(1.4, Padding(
103-
padding: EdgeInsets.all(20.0),
104-
child: MaterialButton(
105-
onPressed: () {},
106-
height: 50,
107-
elevation: 0,
108-
splashColor: Colors.yellow[700],
109-
shape: RoundedRectangleBorder(
110-
borderRadius: BorderRadius.circular(10)
111-
),
112-
color: Colors.yellow[800],
113-
child: Center(
114-
child: Text("Payment", style: TextStyle(color: Colors.white, fontSize: 18),),
115-
),
107+
),
108+
),
109+
FadeAnimation(1.3, Padding(
110+
padding: EdgeInsets.all(20.0),
111+
child: DottedBorder(
112+
color: Colors.grey.shade400,
113+
dashPattern: [10, 10],
114+
padding: EdgeInsets.all(0),
115+
child: Container()
116+
),
117+
)),
118+
FadeAnimation(1.3, Container(
119+
padding: EdgeInsets.symmetric(horizontal: 20),
120+
child: Row(
121+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
122+
children: <Widget>[
123+
Text('Total', style: TextStyle(fontSize: 20)),
124+
Text('\$${totalPrice + 5.99}', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold))
125+
],
126+
),
127+
)),
128+
SizedBox(height: 10),
129+
FadeAnimation(1.4, Padding(
130+
padding: EdgeInsets.all(20.0),
131+
child: MaterialButton(
132+
onPressed: () {},
133+
height: 50,
134+
elevation: 0,
135+
splashColor: Colors.yellow[700],
136+
shape: RoundedRectangleBorder(
137+
borderRadius: BorderRadius.circular(10)
138+
),
139+
color: Colors.yellow[800],
140+
child: Center(
141+
child: Text("Payment", style: TextStyle(color: Colors.white, fontSize: 18),),
116142
),
117-
))
118-
]
119-
)
120-
)
143+
),
144+
))
145+
]
146+
)
121147
);
122148
}
123149

124-
cartItem(Product product, int index) {
150+
cartItem(Product product, int index, animation) {
125151
return GestureDetector(
126152
onTap: () {
127153
Navigator.push(context, MaterialPageRoute(builder: (context) => ProductViewPage(product: product)));
128154
},
129-
child: FadeAnimation(1,
130-
Container(
155+
child: SlideTransition(
156+
position: Tween<Offset>(
157+
begin: const Offset(-1, 0),
158+
end: Offset.zero
159+
).animate(animation),
160+
child: Container(
131161
margin: EdgeInsets.only(bottom: 20),
132162
padding: EdgeInsets.symmetric(horizontal: 10),
133163
decoration: BoxDecoration(

‎pubspec.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ dependencies:
3030
cupertino_icons: ^1.0.2
3131
flashy_tab_bar: ^0.0.3
3232
simple_animations: ^1.3.3
33+
dotted_border: ^2.0.0+1
34+
flutter_slidable: ^0.6.0
3335

3436
dev_dependencies:
3537
flutter_test:

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /