Flutter实现购物车功能(代码+逻辑)
时间:2023-03-02 09:34:53|栏目:Android代码|点击: 次
一、初始化时判断是否为登录状态
假设是登录状态从本地中取出token,带参传递给后端请求登录后购物车数据
二、分析点击全选和非全选状态
1.全选状态就是把数组中的数据对应的每个check值设置为true,总价就是后端返回的全选数量的总价格
设置全选和非全选
这个的改变是由初始化查询数组列表中是否为全选或非全选状态所决定,如果遇见一个check为false那么就返回false
2.非全选状态(总价结果为0或者当前选中对象的总价之和)
判断是否非全选状态
三、改变单个物品check
触发checkCart接口进行更新全选状态的总价,以及当前选中商品总价
四、点击数量增加和减少按钮改变当前显示number值
触发update接口等更新数量,触发查询接口更改选中商品总价,以及全选总价
自定义的数量组件返回的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(); //从缓存中取出当前登录状态 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(){ //初始化的时候监听是否登录 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(){ //迭代循环购物车列表所有checked属性,当全部为true时为全选状态 for (int i = 0; i < _cartList.length; i++) { if (_cartList[i].checked == null || _cartList[i].checked ) { return false; } } return true; } // //判断是否全选 bool _isCheckedAll() { //迭代循环购物车列表所有checked属性,当全部为true时为全选状态 for (int i = 0; i < _cartList.length; i++) { if (_cartList[i].checked == null || !_cartList[i].checked) { return false; } } return true; } //监听刷新事件,当用户从商品详情页面点击添加至购物车时会触发刷新事件 _refreshEvent() { //重新调用接口赋值 CarteventBus.on<RefreshEvent>().listen((RefreshEvent refreshEvent){ if(refreshEvent.isRefresh){ _getCartData(token); } }); CarteventBus.fire(RefreshEvent( false )); } @override Widget build(BuildContext context) { //监听刷新事件 _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; //重新设置全选状态 _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 = { //规格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); } }
上一篇:Android PopUpWindow实现卡片式弹窗
栏 目:Android代码
下一篇:没有了
本文地址:http://www.codeinn.net/misctech/226739.html