Flutter之简单实现购物车功能代码+逻辑

一、初始化时判断是否为登录状态,假设是登录状态从本地中取出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);
  }
}


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可可鸭~

想吃糖~我会甜

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值