59.购物车_计算商品价格和数量

本节课主要是加上自动计算的功能

provide/cart.dart

在provide的类里面增加两个变量

cart_bottom.dart

三个组件因为我们都需要套一层provide所以这里都传入context对象

把三个组件方法,分别都加上context  

引入provide和cart.dart

import 'package:provide/provide.dart';
import '../../provide/cart.dart';

总价

从provide中获取总价,然后赋值

商品的总数量

效果展示

点击删除,总价和商品的数量还没有变化

这是因为没有包裹provide 的原因

我们需要把这里的Row嵌套到Provide里面去

Row嵌套在provide里面即可

用大R进行刷新

最终代码

provide/cart.dart

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
import '../model/cartInfo.dart'; class CartProvide with ChangeNotifier{
String cartString="[]";//声明一个变量 做持久化的存储
List<CartInfoModel> cartList=[];
double allPrice = ;//总价格
int allGoodsCount = ;//商品总数 //声明一个异步的方法,购物车操作放在前台不在请求后台的数据
save(goodsId,goodsName,count,price,images) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
cartString= prefs.getString('cartInfo');//先从持久化中获取
var temp = cartString==null?[]:json.decode(cartString.toString());
//声明list 强制类型是Map
List<Map> tempList=(temp as List).cast();//把temp转成list
bool isHave=false;//是否已经存在了这条记录
int ival=;//foreach循环的索引
//循环判断列表是否存在该goodsId的商品,如果有就数量+1
tempList.forEach((item){
if(item['goodsId']==goodsId){
tempList[ival]['count']=item['count']+;
cartList[ival].count++;
isHave=true;
}
ival++;
});
//没有不存在这个商品,就把商品的json数据加入的tempList中
if(!isHave){
Map<String,dynamic> newGoods={
'goodsId':goodsId,//传入进来的值
'goodsName':goodsName,
'count':count,
'price':price,
'images':images,
'isCheck':true
};
tempList.add(newGoods);
cartList.add(CartInfoModel.fromJson(newGoods));
}
cartString=json.encode(tempList).toString();//json数据转字符串
// print('字符串》》》》》》》》》》》${cartString}');
// print('字符串》》》》》》》》》》》${cartList}'); prefs.setString('cartInfo', cartString);
notifyListeners();
}
remove() async{
SharedPreferences prefs=await SharedPreferences.getInstance();
prefs.remove('cartInfo');
cartList=[];
print('清空完成----------------------');
notifyListeners();
} getCartInfo() async{
SharedPreferences prefs=await SharedPreferences.getInstance();
cartString=prefs.getString('cartInfo');//持久化中获得字符串
print('购物车持久化的数据================>'+cartString);
cartList=[];//把最终的结果先设置为空list
if(cartString==null){
cartList=[];//如果持久化内没有数据 那么就还是空的list
}else{
//声明临时的变量
List<Map> tempList=(json.decode(cartString.toString()) as List).cast();
allPrice=;//价格先初始化为0
allGoodsCount=;//数量先初始化为0
tempList.forEach((item){
if(item['isCheck']){
allPrice+=(item['count']*item['price']);
allGoodsCount +=item['count'];
}
cartList.add(CartInfoModel.fromJson(item));//json转成对象,加入到cartList中
}); }
notifyListeners();//通知
} //删除单个购物车商品
deleteOneGoods(String goodsId) async{
SharedPreferences prefs=await SharedPreferences.getInstance();
cartString=prefs.getString('cartInfo');
List<Map> tempList=(json.decode(cartString.toString()) as List).cast();
int tempIndex=;//定义循环的索引
int deleteIndex=;//要删除的索引
tempList.forEach((item){
if(item['goodsId']==goodsId){
deleteIndex=tempIndex;
}
tempIndex++;
});
tempList.removeAt(deleteIndex);//删除
//删除后转换成string进行持久化
cartString=json.encode(tempList).toString();//list转字符串
prefs.setString('cartInfo', cartString);
await getCartInfo();//重新获取下列表数据,因为getCartInfo方法里面有通知,这里就不再调用了
} }

pages/cart_page/cart_bottom.dart

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provide/provide.dart';
import '../../provide/cart.dart'; class CartBottom extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(5.0),
color: Colors.white,
child: Provide<CartProvide>(
builder: (context,child,val){
return Row(
children: <Widget>[
_selectAllBtn(context),
_allPriceArea(context),
_goButton(context)
],
);
}
)
);
}
//全选
Widget _selectAllBtn(context){
return Container(
child: Row(
children: <Widget>[
Checkbox(
value: true,
activeColor: Colors.pink,//激活的颜色
onChanged: (bool val){},//事件
),
Text('全选')
],
),
);
}
//合计
Widget _allPriceArea(context){
double allPrice = Provide.value<CartProvide>(context).allPrice;
return Container(
width: ScreenUtil().setWidth(),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
alignment: Alignment.centerRight,
width: ScreenUtil().setWidth(),
child: Text(
'合计:',
style:TextStyle(
fontSize:ScreenUtil().setSp()
)
),
),
//红色的价格
Container(
alignment: Alignment.centerLeft,
width: ScreenUtil().setWidth(),
child: Text(
'${allPrice}',
style: TextStyle(
fontSize: ScreenUtil().setSp(),
color: Colors.red
)
),
)
],
),
//第二行
Container(
width: ScreenUtil().setWidth(),//和第一行一样宽
alignment: Alignment.centerRight,
child: Text(
'满10元免配送费,预购免配送费',
style: TextStyle(
color: Colors.black38,
fontSize: ScreenUtil().setSp()
),
),
)
],
),
);
} //结算 用 inkWell
Widget _goButton(context){
int allGoodsCount= Provide.value<CartProvide>(context).allGoodsCount;
return Container(
width: ScreenUtil().setWidth(),
padding: EdgeInsets.only(left:10.0),
child: InkWell(
onTap: (){},
child: Container(
padding: EdgeInsets.all(10.0),
alignment: Alignment.center,//居中对齐
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(3.0)//圆角
),
child: Text(
'结算(${allGoodsCount})',
style: TextStyle(
color: Colors.white
),
),
),
),
);
}
}

Flutter实战视频-移动电商-59.购物车_计算商品价格和数量的更多相关文章

  1. Flutter实战视频-移动电商-52.购物车_数据模型建立和Provide修改

    52.购物车_数据模型建立和Provide修改 根据json数据生成模型类 {,"price":830.0,"images":"http://imag ...

  2. Flutter实战视频-移动电商-53.购物车_商品列表UI框架布局

    53.购物车_商品列表UI框架布局 cart_page.dart 清空原来写的持久化的代码; 添加对应的引用,stless生成一个静态的类.建议始终静态的类,防止重复渲染 纠正个错误,上图的CartP ...

  3. Flutter实战视频-移动电商-54.购物车_商品列表子项布局

    54.购物车_商品列表子项布局 子项做成一个单独的页面 新建cartItem.dart文件 新建cart_page文件夹,在里面新建cart_item.dart页面, 页面名字叫做CartItem 定 ...

  4. Flutter实战视频-移动电商-55.购物车_底部结算栏UI制作

    55.购物车_底部结算栏UI制作 主要做下面结算这一栏目 cart_bottom.dart页面 先设置下内边距 拆分成三个子元素 全选 因为有一个文本框和一个全选的text文本,所以这里也用了Row布 ...

  5. Flutter实战视频-移动电商-56.购物车_商品数量控制区域制作

    56.购物车_商品数量控制区域制作 主要做购物车中的数量这里 cart_page文件夹下新建cart_count.dart 减少按钮 因为会有点击事件,所以这里我们使用InkWell. child里面 ...

  6. Flutter实战视频-移动电商-57.购物车_在Model中增加选中字段

    57.购物车_在Model中增加选中字段 先修改model类 model/cartInfo.dart类增加是否选中的属性 修改provide 修改UI部分pages/cart_page/cart_it ...

  7. Flutter实战视频-移动电商-58.购物车_删除商品功能制作

    58.购物车_删除商品功能制作 主要做购物车后面的删除按钮 删除的方法写在provide里面 provide/cart.dart文件 传入goodsId,循环对比,找到后进行移除 //删除单个购物车商 ...

  8. Flutter实战视频-移动电商-60.购物车_全选按钮的交互效果制作

    60.购物车_全选按钮的交互效果制作 主要做全选和复选框的这两个功能 provide/cart.dart 业务逻辑写到provide里面 先持久化取出来字符串,把字符串编程list.循环list ca ...

  9. Flutter实战视频-移动电商-61.购物车_商品数量的加减操作

    61.购物车_商品数量的加减操作 provide/cart.dart pages/cart_page/cart_count.dart 先引入provide和cartProvide 定义接收一个item ...

随机推荐

  1. 斯坦福公开课:Developing IOS 8 App with Swift(1-3)心得体会

    最近开始学习Swift开发移动程序.跟随斯坦福大学的公开课进行自学. 这真是一个美好的时代,虽然不能在斯坦福求学,但是可以观看录制的授课录像.讲义,好似老师在给我们上课一样! 心得: 1.每节课信息量 ...

  2. 基于bootstrap+MySQL搭建动态网站

    这个只是在上个练习项目中的后台管理项目加入了MySQL,数据不是写死的,而是从数据库中获取到的,获取到数据执行增删改查操作,没什么 计数难度,不做介绍

  3. 虚拟网卡TUN/TAP 驱动程序设计原理

    昨天韦哥写了<Linux下Tun/Tap设备通信原理>一文,只提到了两个使用Tun的用户进程之间的通信路径,并没有说明Tun虚拟网卡驱动是如何实现的,而正好看到了这里的一篇讲解这方面的文章 ...

  4. caffe搭建----Visual Studio 2015+CUDA8.0+CUDNN5配置Caffe-windows(BLVC)

    原文来源:  来源:Angle_Cal  2016-12-19 17:32 本博主修改于2017-09-12.  版权所有,转载请注明出处.   BLVC版本的Caffe-windows已经支持Vis ...

  5. 【BZOJ1844/2210】Pku1379 Run Away 模拟退火

    [BZOJ1844/2210]Pku1379 Run Away 题意:矩形区域中有一堆点,求矩形中一个位置使得它到所有点的距离的最小值最大. 题解:模拟退火的裸题,再调调调调调参就行了~ #inclu ...

  6. Hibernate中的事务处理流程详解

    一.Hibernate操作的基本流程 使用 Hibernate 进行数据持久化操作,通常有如下步骤: 1.编写持久化类: POJO + 映射文件 2.获取 Configuration 对象 3.获取 ...

  7. Struts2中的OGNL表达式

    一.OGNL表达式简介 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,它是一个开源项目.所谓对象图,即以任意一个对象为根,通过OGNL可以访问 ...

  8. 九度OJ 1140:八皇后 (八皇后问题)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:795 解决:494 题目描述: 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * ...

  9. redis的主从复制和哨兵支持的主从切换

    1 主从复制的目的是为了读写分离 master写,然后同步到slave,slave只管读. 2 哨兵存在的目的 是为了主从切换,如果master挂了,那么一个slave成为master,重启之后的ma ...

  10. Hadoop实战-Flume之Hdfs Sink(十)

    a1.sources = r1 a1.sinks = k1 a1.channels = c1 # Describe/configure the source a1.sources.r1.type = ...