文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Flutter实现购物车功能(代码+逻辑)

2024-04-02 19:55

关注

一、初始化时判断是否为登录状态

假设是登录状态从本地中取出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);
  }
}


 到此这篇关于Flutter实现购物车功能(代码+逻辑)的文章就介绍到这了,更多相关Flutter 购物车内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯