Flutter實戰視頻-移動電商-60.購物車_全選按鈕的交互效果製做

60.購物車_全選按鈕的交互效果製做

主要作全選和複選框的這兩個功能編程

provide/cart.dart

業務邏輯寫到provide裏面json

先持久化取出來字符串,把字符串編程list。循環listless

cart_page/cart_item.dart

每一項的複選框的事件異步

單個複選框的效果預覽

所有取消,價格和數量都發生了變化async

全選按鈕

全選單獨聲明一個變量,ide

而後咱們須要在獲取所有購物車列表的方法裏面作一些事情ui

循環以前先初始化爲true,循環的時候只要是有沒選中的那麼全選就是falsespa

 

cart_page/cart_bottom.dart

只要有一個沒有選中,就不會都選中3d

全選中,全選的付款狂也是選中的狀態code

全選按鈕的事件

provide/cart.dart中要單獨寫一個方法

 新增點擊全選和取消全選的方法

 

效果展現

點擊後都取消了選擇的狀態

 

最終代碼:

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 = 0;//總價格
  int allGoodsCount = 0;//商品總數
  bool isAllCheck=true;//全選 默認true

  //聲明一個異步的方法,購物車操做放在前臺不在請求後臺的數據
  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=0;//foreach循環的索引
    //循環判斷列表是否存在該goodsId的商品,若是有就數量+1
    tempList.forEach((item){
      if(item['goodsId']==goodsId){
        tempList[ival]['count']=item['count']+1;
        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;//價格先初始化爲0
      allGoodsCount=0;//數量先初始化爲0
      isAllCheck=true;//循環以前初始化一下
      tempList.forEach((item){
        if(item['isCheck']){
          allPrice+=(item['count']*item['price']);
          allGoodsCount +=item['count'];
        }else{
          isAllCheck=false;
        }
        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=0;//定義循環的索引
    int deleteIndex=0;//要刪除的索引
    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方法裏面有通知,這裏就再也不調用了
  }

  changeCheckState(CartInfoModel cartItem) async{
    SharedPreferences prefs=await SharedPreferences.getInstance();
    cartString=prefs.getString('cartInfo');
    List<Map> tempList=(json.decode(cartString.toString()) as List).cast();
    int tempIndx=0;//歷史索引
    int changeIndex=0;//改變的索引
    tempList.forEach((item){
      if(item['goodsId']==cartItem.goodsId){
        changeIndex=tempIndx;
      }
      tempIndx++;
    });

    tempList[changeIndex]=cartItem.toJson();//toJson就變成了Map值
    cartString=json.encode(tempList).toString();
    prefs.setString('cartInfo', cartString);

    await getCartInfo();//再次從新獲取購物車的數據
  }

  //點擊全選按鈕操做
  changeAllCheckBtnState(bool isCheck) async{
    SharedPreferences prefs=await SharedPreferences.getInstance();
    cartString=prefs.getString('cartInfo');
    List<Map> tempList=(json.decode(cartString.toString()) as List).cast();
    List<Map> newList=[];//這裏必須初始化爲[]聲明爲一個空的值
    
    for(var item in tempList)
    {
      //dart在循環的時候是不容許改變老的值的
      var newItem=item;//把老的item賦值給新的item
      newItem['isCheck']=isCheck;
      newList.add(newItem);
    }

    cartString=json.encode(newList).toString();
    prefs.setString('cartInfo', cartString);

    await getCartInfo();//最後中心獲取一下購物車的列表數據
  }


}
View Code

 

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){
    bool isAllCheck=Provide.value<CartProvide>(context).isAllCheck;
    return Container(
      child: Row(
        children: <Widget>[
          Checkbox(
            value: isAllCheck,
            activeColor: Colors.pink,//激活的顏色
            onChanged: (bool val){
              Provide.value<CartProvide>(context).changeAllCheckBtnState(val);
            },//事件
          ),
          Text('全選')
        ],
      ),
    );
  }
  //合計
  Widget _allPriceArea(context){
    double allPrice = Provide.value<CartProvide>(context).allPrice;
    return Container(
      width: ScreenUtil().setWidth(430),
      child: Column(
        children: <Widget>[
          Row(
            children: <Widget>[
              Container(
                alignment: Alignment.centerRight,
                width: ScreenUtil().setWidth(280),
                child: Text(
                  '合計:',
                  style:TextStyle(
                    fontSize:ScreenUtil().setSp(36)
                  )
                ),
              ),
              //紅色的價格
              Container(
                alignment: Alignment.centerLeft,
                width: ScreenUtil().setWidth(150),
                child: Text(
                  '${allPrice}',
                  style: TextStyle(
                     fontSize: ScreenUtil().setSp(36),
                     color: Colors.red
                  )
                ),
              )
            ],
          ),
          //第二行
          Container(
            width: ScreenUtil().setWidth(430),//和第一行同樣寬
            alignment: Alignment.centerRight,
            child: Text(
              '滿10元免配送費,預購免配送費',
              style: TextStyle(
                color: Colors.black38,
                fontSize: ScreenUtil().setSp(22)
              ),
            ),
          )
        ],
      ),
    );
  }

  //結算 用 inkWell
  Widget _goButton(context){
    int allGoodsCount= Provide.value<CartProvide>(context).allGoodsCount;
    return Container(
      width: ScreenUtil().setWidth(160),
      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
            ),
          ),
        ),
      ),
    );
  }
}
View Code
相關文章
相關標籤/搜索