Flutter實現購物車功能(代碼+邏輯)
一、初始化時判斷是否為登錄狀態(tài)
假設是登錄狀態(tài)從本地中取出token,帶參傳遞給后端請求登錄后購物車數據




二、分析點擊全選和非全選狀態(tài)
1.全選狀態(tài)就是把數組中的數據對應的每個check值設置為true,總價就是后端返回的全選數量的總價格


設置全選和非全選

這個的改變是由初始化查詢數組列表中是否為全選或非全選狀態(tài)所決定,如果遇見一個check為false那么就返回false
2.非全選狀態(tài)(總價結果為0或者當前選中對象的總價之和)
判斷是否非全選狀態(tài)


三、改變單個物品check
觸發(fā)checkCart接口進行更新全選狀態(tài)的總價,以及當前選中商品總價



四、點擊數量增加和減少按鈕改變當前顯示number值
觸發(fā)update接口等更新數量,觸發(fā)查詢接口更改選中商品總價,以及全選總價


自定義的數量組件返回的value是當前增加或減少改變后的number值



五、長按刪除數據
調用刪除接口重新渲染頁面

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:myshop_flutter/components/gradient_button.dart';
import 'package:myshop_flutter/config/colours.dart';
import 'package:myshop_flutter/config/index.dart';
import 'package:myshop_flutter/event/cart_number_event.dart';
import 'package:myshop_flutter/event/category_event.dart';
import 'package:myshop_flutter/event/login_event.dart';
import 'package:myshop_flutter/event/refresh_event.dart';
import 'package:myshop_flutter/model/cart_list_model.dart';
import 'package:myshop_flutter/page/CategoryPage/GoodCategory/GooddetailWidget/cart_number_widget.dart';
import 'package:myshop_flutter/service/cart_service.dart';
import 'package:myshop_flutter/utils/navigator_util.dart';
import 'package:myshop_flutter/utils/shared_preferences_util.dart';
import 'package:myshop_flutter/utils/toast_util.dart';
import 'package:myshop_flutter/widgets/cached_image_widget.dart';
import 'package:shared_preferences/shared_preferences.dart';
class CartPage extends StatefulWidget {
const CartPage({Key key}) : super(key: key);
@override
_CartPageState createState() => _CartPageState();
}
class _CartPageState extends State<CartPage> {
//購物車數據服務
CartService _cartService = CartService();
//購物車列表數據
List<CartModel> _cartList;
//購物車列表數據模型
CartListModel _cartListModel;
//是否登錄
bool _isLogin = false;
//是否全選
bool _isAllCheck = false;
//是否全都不選
bool _isAllNotCheck = false;
//總計
double _totalMoney;
//token
var token;
//獲取當前查詢購物車中選中的商品數量
var _checkedGoodsAmount;
@override
void initState() {
super.initState();
//從緩存中取出當前登錄狀態(tài)
SharedPreferencesUtil.getLoginSave().then((v){
print("登錄購物車頁面獲取本地登錄值${v}");
if(v){
setState(() {
_isLogin = v;
});
//刷新購物車數據
//從緩存中取出當前的token值
SharedPreferencesUtil.getToken().then((onValue) {
if(onValue!=null){
_getCartData(onValue);
setState(() {
token = onValue;
});
}
});
}
});
}
_listener(){
//初始化的時候監(jiān)聽是否登錄
loginEventBus.on<LoginEvent>().listen((LoginEvent loginEvent) {
print("購物車頁面是否判定登錄");
setState(() {
_isLogin = loginEvent.isLogin;
});
});
}
//獲取購物車數據
_getCartData(token) {
print("---------${token}");
//將token值放入請求頭里
Options options = Options(headers:{"X-Shop-Token" : token});
//查詢購物車數據
_cartService.queryCart((cartList) {
setState(() {
_cartListModel = cartList;
_cartList = _cartListModel.cartList;
_checkedGoodsAmount = _cartListModel.cartTotal.checkedGoodsAmount;
_totalMoney = _cartListModel.cartTotal.goodsAmount;
});
//是否全選
_isAllCheck = _isCheckedAll();
_isAllNotCheck = _isNotCheckedAll();
}, (error) {
ToastUtil.showToast(error);
},options:options);
}
//判斷是否全部不選,如果有一個等于true就返回false
_isNotCheckedAll(){
//迭代循環(huán)購物車列表所有checked屬性,當全部為true時為全選狀態(tài)
for (int i = 0; i < _cartList.length; i++) {
if (_cartList[i].checked == null || _cartList[i].checked ) {
return false;
}
}
return true;
}
// //判斷是否全選
bool _isCheckedAll() {
//迭代循環(huán)購物車列表所有checked屬性,當全部為true時為全選狀態(tài)
for (int i = 0; i < _cartList.length; i++) {
if (_cartList[i].checked == null || !_cartList[i].checked) {
return false;
}
}
return true;
}
//監(jiān)聽刷新事件,當用戶從商品詳情頁面點擊添加至購物車時會觸發(fā)刷新事件
_refreshEvent() {
//重新調用接口賦值
CarteventBus.on<RefreshEvent>().listen((RefreshEvent refreshEvent){
if(refreshEvent.isRefresh){
_getCartData(token);
}
});
CarteventBus.fire(RefreshEvent(
false
));
}
@override
Widget build(BuildContext context) {
//監(jiān)聽刷新事件
_listener();
_refreshEvent();
return _isLogin == true
? Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("購物車"),
),
body: _cartList.length == 0?
Container(
padding: EdgeInsets.only(top: 70),
child: Center(
child: Column(
children: [
Image.asset(
"images/emptycar.png",
width: 135,
height: 135,
),
SizedBox(
height: 46,
),
Text(
"還沒有添加任何商品,快去選購吧!",
style: TextStyle(
fontSize: 15, color: Colours.textBlack32),
),
SizedBox(
height: 80,
),
GestureDetector(
onTap: () {
// Navigator.pop(context);
},
child: Container(
alignment: Alignment.center,
width: 100,
height: 40,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colours.directBB1,
Colours.directBB2,
],
end: Alignment.bottomCenter,
begin: Alignment.topCenter,
),
borderRadius: BorderRadius.circular(150),
),
child: Text(
"去逛逛",
style: TextStyle(
color: Colors.white, fontSize: 16),
),
),
),
],
),
),
)
: Stack(
alignment: Alignment.bottomCenter,
children: <Widget>[
//渲染購物車列表數據
ListView.builder(
//購物車列表項個數
itemCount: _cartList.length,
//購物車列表項構建器
itemBuilder: (BuildContext context, int index) {
//根據索引返回列表項
return _getCartItemWidget(index);
}),
Container(
height: 60,
decoration:BoxDecoration(
color: Colors.white,
),
//水平布局
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
flex: 3,
child: Row(
children: [
//全選復選框
Checkbox(
value: _isAllCheck,
activeColor: KColor.defaultCheckBoxColor,
//選擇改變事件回調
onChanged: (bool) {
//設置是否全選
_setCheckedAll(bool);
}),
Text("全選"),
Expanded(
child: Container(
alignment: Alignment.centerRight,
margin: EdgeInsets.only(right: 20),
//全選價格
child: Text(_isAllCheck
? KString.TOTAL_MONEY +"${_totalMoney}"
: _isNotCheckedAll == true ? KString.TOTAL_MONEY +"0.0":KString.TOTAL_MONEY + "${_checkedGoodsAmount}"),
)),
],
)),
Expanded(
flex: 1,
child: Container(
margin: EdgeInsets.only(
right:
30,
),
alignment: Alignment.centerRight,
//結算按鈕
child: RaisedButton(
//結算操作
onPressed: () {
//跳轉到填寫訂單頁面
_fillInOrder();
},
color: KColor.defaultButtonColor,
child: Text(
//結算標簽
KString.SETTLEMENT,
style: TextStyle(
color: Colors.white,
fontSize:17),
),
),
),
),
],
),
)
],
))
: Scaffold(
appBar: AppBar(
elevation: 0,
centerTitle: true,
title: Text(
"購物車",
style: TextStyle(color: Colors.white),
),
backgroundColor: Colors.lightBlueAccent,
),
body: Container(
child: Column(
children: [
SizedBox(
height: 40,
),
Container(
alignment: Alignment.center,
child: Image.asset(
"images/wukong.png",
height: 60,
width: double.infinity,
),
),
Center(
child: Text("還沒有登錄哦"),
),
GestureDetector(
onTap: () {},
child: Padding(
padding: EdgeInsets.fromLTRB(30, 10, 30, 0),
child:
GradientButton("去登錄", 0xFFFF9E00, 0xFFFF4800, () {
NavigatorUtil.goLogin(context);
}, textSize: 18, textColor: 0xFFFEFEFE),
))
],
),
),
);
}
//跳轉至填寫訂單頁面
_fillInOrder() {
NavigatorUtil.goFillInOrder(context, 0);
}
//設置是否全選/全不選
_setCheckedAll(bool checked) {
setState(() {
_isAllCheck = checked;
for (int i = 0; i < _cartList.length; i++) {
_cartList[i].checked = checked;
}
});
}
//刪除對話框
_deleteDialog(int index) {
return showDialog<void>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return AlertDialog(
//提示
title: Text(KString.TIPS),
//是否確認刪除
content: Text(KString.DELETE_CART_ITEM_TIPS),
actions: <Widget>[
//取消按鈕
FlatButton(
onPressed: () {
Navigator.pop(context);
},
child: Text(
KString.CANCEL,
style: TextStyle(color: Colors.black54),
),
),
//刪除按鈕
FlatButton(
onPressed: () {
//刪除商品
_deleteGoods(index);
},
child: Text(
KString.CONFIRM,
style: TextStyle(color: KColor.defaultTextColor),
),
)
],
);
});
}
//根據索引刪除購物車商品
_deleteGoods(int index) {
//獲取token值
Options options = Options(headers:{"X-Shop-Token" : token});
//通過索引獲取到產品Id
var parameters = {
"productIds": [_cartList[index].productId]
};
//調用刪除商品方法
_cartService.deleteCart((success) {
//刪除成功提示
ToastUtil.showToast(KString.DELETE_SUCCESS);
setState(() {
//本地列表移除數據
_cartList.removeAt(index);
});
Navigator.pop(context);
}, (error) {
ToastUtil.showToast(error);
}, parameters,options:options);
}
//根據索引獲取購物車項組件
Widget _getCartItemWidget(int index) {
return Container(
height:130,
width: double.infinity,
child: InkWell(
//長按打開刪除商品對話框
onLongPress: () => _deleteDialog(index),
child: Card(
//水平布局
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
//是否勾選此商品
Checkbox(
//讀取購物車列表數據中當前項的checked值
value: _cartList[index].checked ?? true,
activeColor: KColor.defaultCheckBoxColor,
//改變回調方法
onChanged: (bool) {
_checkCart(index, bool);
}),
//緩存商品圖片
CachedImageWidget(
80,
80,
//商品圖片路徑
_cartList[index].picUrl,
),
//垂直布局
SizedBox(width: 30,),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//商品名稱
Text(
_cartList[index].goodsName,
style: TextStyle(
fontSize:16,
color: Colors.black54),
),
Padding(
padding: EdgeInsets.only(
top: 10,
),
),
//商品價格
Text(
"¥${_cartList[index].price}",
style: TextStyle(
fontSize: 16,
color: Colors.grey),
)
],
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//購買商品數量
Text(
"X${_cartList[index].number}",
style: TextStyle(
color: Colors.black54,
fontSize: 16),
),
Padding(
padding: EdgeInsets.only(
top:10,
),
),
//使用購物數量組件
CartNumberWidget(_cartList[index].number, (value) {
//根據返回的索引及數量更新購物車
_updateCart(index, value);
}),
],
))
],
),
),
),
);
}
//是否勾選商品,傳入索引及是否勾選
_checkCart(int index, bool isCheck) {
Options options = Options(headers:{"X-Shop-Token" : token});
var parameters = {
//產品Id
"productIds": [_cartList[index].productId],
//是否選擇
"isChecked": isCheck ? 1 : 0,
};
//調用購物車數據服務方法
_cartService.cartCheck((success) {
setState(() {
_cartListModel = success;
_cartList = _cartListModel.cartList;
//重新設置全選狀態(tài)
_isAllCheck = _isCheckedAll();
//計算總價
_checkedGoodsAmount = _cartListModel.cartTotal.checkedGoodsAmount;
_totalMoney = _cartListModel.cartTotal.goodsAmount;
});
}, (error) {
ToastUtil.showToast(error);
}, parameters,options);
}
//更新購物車,傳入索引及數量
_updateCart(int index, int number) {
Options options = Options(headers:{"X-Shop-Token" : token});
var parameters = {
//規(guī)格Id
"productId": _cartList[index].productId,
//商品Id
"goodsId": _cartList[index].goodsId,
//商品數量
"number": number,
//id
"id": _cartList[index].id,
};
_cartService.updateCart((success) {
setState(() {
_cartList[index].number = number;
});
_getCartData(token);
}, (error) {
ToastUtil.showToast(error);
cartNumberEventBus.fire(CartNumberEvent(number - 1));
}, options, parameters);
}
}
到此這篇關于Flutter實現購物車功能(代碼+邏輯)的文章就介紹到這了,更多相關Flutter 購物車內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Android Native 內存泄漏系統(tǒng)化解決方案
這篇文章主要介紹了Android Native 內存泄漏系統(tǒng)化解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-07-07
Android開發(fā)之sqlite3命令行簡單使用方法
這篇文章主要介紹了Android開發(fā)之sqlite3命令行簡單使用方法,分析了Android增刪改查等常用sqlite3的數據庫操作命令使用方法,需要的朋友可以參考下2016-02-02
Android開發(fā)基礎之創(chuàng)建啟動界面Splash Screen的方法
這篇文章主要介紹了Android開發(fā)基礎之創(chuàng)建啟動界面Splash Screen的方法,以實例形式較為詳細的分析了Android定制啟動界面的布局及功能實現相關技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-10-10

