项目git地址:flower_gift
这次的内容是购物车界面的各种逻辑完成。还是先简单看看效果:
先说明一下,对于Provide的运用,只要把购物车这一个页面的逻辑理清楚,用好这个数据管理,那么Provide的运用应该就没有什么大问题了。 其次是本来这个是有后台交互的购物车,这样没什么难度,我也就基本也按照技术胖的教学课程来重新做了一次购物车,收获蛮大的。 下面还是就分环节介绍吧
本地数据持久化方案-- shared_preferences
这个东西呢,有点像iOS中的NSUserDefaults,也是依靠键值对存储数据,可以存储一些像int,String,List等一些数据到本地,很轻量级,使用也比较方便,只需要简单学习一些就可以上手了
tabBar栏的简单的切换逻辑
在最初搭建页面框架的时候,我就已经创建了一个TabBarTapProvide来管理底部tab标签栏的切换,所以我们在商品详情页,要想直接跳转到购物车tab页面就很简单了
找到商品详情页的detailsBottom_widget
InkWell(
onTap: (){
//改变tab的选中index来控制底部tab的切换
Provide.value(context).bottomTabBarTap(3);
//pop出当前页面
Navigator.pop(context);
},
在购物车点击里面加上这个代码即可
整个购物车Provide文件
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import '../model/cartInfo_model_entity.dart';
//购物车简单逻辑:
/*
* 因为我们这边购物车就不去和后台交互了,这样比较简单,我们就采用这个本地存储数据
* 的方式来做。
* 大概思路也就是在加入购物车的时候将商品的几个关键数据,先做成数据字典,然后加入到
* 购物车List中,最后将这个List转化为String存储,取出的时候,先将String转为List来进行操作
*
*/
final cartInfoKey = "cartInfo";
class CartProvide with ChangeNotifier{
String cartString = "[]";
List cartList = [];
double allPrice = 0;//总价格
int allGoodsCount = 0;//商品总数量
bool isAllSelect = true;//是否全选
//存储商品
saveGoods(goodsId,goodsName,count,price,images) async{
SharedPreferences prefs = await SharedPreferences.getInstance();
//首先获取数据库中的数据(String 类型)
cartString = prefs.getString(cartInfoKey);
//类型转换
var temp = cartString==null?[]:json.decode(cartString.toString());
List
逻辑不算复杂,但是各个操作比较多,得细心点,SharedPreferences的使用很简单,key最好单独提出来写成一个常量。还有就是dart语言的基础还是有必要去简单过一下,不然有些东西就只知道写这个,不知道为什么要写这个东东。
购物车界面
import 'package:flutter/material.dart';
import 'package:provide/provide.dart';
import '../provide/cart_provide.dart';
import './cartSubWidget/cart_bottom.dart';
import './cartSubWidget/cart_item.dart';
class CarShopPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("购物车"),
),
body: FutureBuilder(
future: _getCartInfo(context),
builder: (context,snapshot){
if(snapshot.hasData){
List cartList = Provide.value(context).cartList;
return Stack(
children: [
Provide(
builder: (context,child,value){
cartList = Provide.value(context).cartList;
return ListView.builder(
itemCount: cartList.length,
itemBuilder: (context,index){
return CartItem(cartList[index]);
},
);
},
),
Positioned(
bottom: 0,
left: 0,
child: CartBottom(),
)
],
);
}else{
return Text("购物车是空的哦!");
}
},
),
);
}
//数据加载(本地获取)
Future _getCartInfo(BuildContext context) async{
await Provide.value(context).getCartInfo();
return "加载成功";
}
}
注意对于要实时更新的UI一定要放在Provide widget中
购物车拆分widget
cartItem.dart
import 'package:flutter/material.dart';
import '../../model/cartInfo_model_entity.dart';
import './cart_count.dart';//加减组件
import 'package:provide/provide.dart';
import '../../provide/cart_provide.dart';
class CartItem extends StatelessWidget {
final CartInfoModel item;
CartItem(this.item);
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.fromLTRB(5.0, 2.0, 5.0, 2.0),
padding: EdgeInsets.fromLTRB(5.0, 10.0, 5.0, 10.0),
decoration: BoxDecoration(
color: Colors.white,
border: Border(
bottom: BorderSide(width: 1,color:Colors.black12)
)
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_cartCheckBtn(context,item),
_cartImage(context,item),
_cartGoodsName(context,item),
_cartPrice(context,item),
],
),
);
}
//选择按钮
Widget _cartCheckBtn(BuildContext context,CartInfoModel item){
return Container(
width: MediaQuery.of(context).size.width / 10,
child: Checkbox(
value: item.isCheck,
activeColor: Colors.orangeAccent,
onChanged: (bool val){
item.isCheck = val;//改变选中状态了
Provide.value(context).changeSelectState(item);
},
),
);
}
//商品图片
Widget _cartImage(BuildContext context,CartInfoModel item){
return Container(
width: MediaQuery.of(context).size.width / 5,
padding: EdgeInsets.all(3.0),
decoration: BoxDecoration(
border: Border.all(width: 1,color: Colors.black12)
),
child: Image.network(item.images),
);
}
//商品名称
Widget _cartGoodsName(BuildContext context,CartInfoModel item){
return Container(
width: MediaQuery.of(context).size.width / 10 * 4,
padding: EdgeInsets.all(10.0),
alignment: Alignment.topLeft,
child: Column(
children: [
Text(item.goodsName),
SizedBox(height: 10.0,),
CartCount(item)
],
),
);
}
//商品价格
Widget _cartPrice(BuildContext context,CartInfoModel item){
return Container(
width: MediaQuery.of(context).size.width / 10 * 2,
alignment: Alignment.centerRight,
child: Column(
children: [
Text(
"¥${item.price}",
style: TextStyle(
color: Colors.orangeAccent
),
),
SizedBox(height: 15.0,),
Container(
child: InkWell(
onTap: (){
print("删除商品");
Provide.value(context).deleteSingleGoods(item.goodsId);
},
child: Icon(
Icons.delete_forever,
color:Colors.black26,
size: 30.0,
),
),
)
],
),
);
}
}
cartBottom.dart
import 'package:flutter/material.dart';
import 'package:provide/provide.dart';
import '../../provide/cart_provide.dart';
final double cartBottomFontS = 20.0;
class CartBottom extends StatelessWidget {
const CartBottom({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(5.0),
color: Colors.black12.withAlpha(15),
child: Provide(
builder: (context,child,val){
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_selectAll(context),
_allPriceArea(context),
_goButton(context),
],
);
},
)
);
}
//全选按钮
Widget _selectAll(BuildContext context){
return Container(
width:(MediaQuery.of(context).size.width - 10)/10 * 3,
child: Row(
children: [
Checkbox(
value: Provide.value(context).isAllSelect,
activeColor: Colors.orangeAccent,
onChanged: (bool val){
print("点击了全选按钮");
Provide.value(context).changeAllCheckBtnState(val);
},
),
Text("全选",
style: TextStyle(
fontSize: cartBottomFontS
),
)
],
),
);
}
//合计区域
Widget _allPriceArea(BuildContext context){
double allPrice = Provide.value(context).allPrice;
return Container(
width:(MediaQuery.of(context).size.width - 10)/10 * 4,
child: Column(
children: [
Row(
children: [
Container(
alignment: Alignment.centerRight,
child: Text("合计:",
style: TextStyle(
fontSize: cartBottomFontS
),
),
),
Container(
alignment: Alignment.centerLeft,
child: Text(
"¥${allPrice}",
style:TextStyle(
color:Colors.orangeAccent,
fontSize: cartBottomFontS,
)
),
)
],
),
],
),
);
}
//结算
Widget _goButton(BuildContext context){
int allGoodsCount = Provide.value(context).allGoodsCount;
return Container(
width:(MediaQuery.of(context).size.width - 10)/10 *3,
height: 40.0,
padding: EdgeInsets.only(left: 10.0),
child: InkWell(
onTap: (){},
child: Container(
padding: EdgeInsets.all(10.0),
alignment: Alignment.center,
decoration: BoxDecoration(
color:Colors.orangeAccent,
borderRadius: BorderRadius.circular(5.0)
),
child: Text(
"结算(${allGoodsCount})",
style:TextStyle(
color:Colors.white,
fontSize: 15.0,
)
),
),
),
);
}
}
cartCount.dart
import 'package:flutter/material.dart';
import 'package:provide/provide.dart';
import '../../provide/cart_provide.dart';
import '../../model/cartInfo_model_entity.dart';
class CartCount extends StatelessWidget {
CartInfoModel item;
CartCount(this.item);
@override
Widget build(BuildContext context) {
var cWidth = (MediaQuery.of(context).size.width) / 10 * 4 * 0.7;
return Provide(
builder: (context,child,val){
return Container(
width: cWidth,
margin: EdgeInsets.only(top: 5.0),
decoration: BoxDecoration(
border: Border.all(width: 1,color: Colors.black12)
),
child: Row(
children: [
_reduceBtn(context,cWidth,item),
_countArea(context,cWidth,item),
_addBtn(context,cWidth,item)
],
),
);
},
);
}
//减少按钮
Widget _reduceBtn(BuildContext context,cWidth,CartInfoModel cartItem){
return InkWell(
onTap: (){
print("点击了减少按钮");
Provide.value(context).addOrReduceAction(cartItem, "reduce");
},
child: Container(
width: cWidth / 4 +4,
height: cWidth / 4 * 0.8,
alignment: Alignment.center,
decoration: BoxDecoration(
color: item.count>1 ? Colors.white : Colors.black12,
border: Border(
right: BorderSide(width: 1,color:Colors.black12)
)
),
child: Text("-"),
),
);
}
//中间数字
Widget _countArea(BuildContext context,cWidth,CartInfoModel cartItem){
return Container(
width: cWidth / 4 * 2 -10.0,
height: cWidth / 4 * 0.8,
alignment: Alignment.center,
color: Colors.white,
child: Text("${cartItem.count}"),
);
}
//增加按钮
Widget _addBtn(BuildContext context,cWidth,CartInfoModel cartItem){
return InkWell(
onTap: (){
print("点击了加好按钮");
Provide.value(context).addOrReduceAction(cartItem, "add");
},
child: Container(
width: cWidth / 4+4,
height: cWidth / 4 * 0.8,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.white,
border: Border(
left: BorderSide(width: 1,color:Colors.black12)
)
),
child: Text("+"),
),
);
}
}