主要实现点击小类下面的列表跟着切换

获取右侧下面的列表信息,即要传递大类的id也要传递小类的,所以需要把左侧的大类的id也要Provide化

可以看下网站上的接口说明:

https://jspang.com/posts/2019/03/01/flutter-shop.html#%E5%90%8E%E7%AB%AF%E6%8E%A5%E5%8F%A3api%E6%96%87%E6%A1%A3

Flutter移动电商实战 --(33)列表页_子类和商品列表交互效果_ide

大类id Provide化

当我们点击左侧的大类的时候,要把当前的大类id存起来。

Flutter移动电商实战 --(33)列表页_子类和商品列表交互效果_flutter_02

category_page.dart

我们修改了上面的多传递了参数以后,那么category_page.dart页面地方就会报错了

Flutter移动电商实战 --(33)列表页_子类和商品列表交互效果_flutter_03

分别传入我们的大类id

Flutter移动电商实战 --(33)列表页_子类和商品列表交互效果_ide_04

这我们去掉async和await修饰符

Flutter移动电商实战 --(33)列表页_子类和商品列表交互效果_子类_05

我们把这个_getGoodsList方法复制一个 到下面

Flutter移动电商实战 --(33)列表页_子类和商品列表交互效果_ide_06

复制到 _rightInkWell方法下面

Flutter移动电商实战 --(33)列表页_子类和商品列表交互效果_子类_07

Flutter移动电商实战 --(33)列表页_子类和商品列表交互效果_flutter 项目实战_08

Flutter移动电商实战 --(33)列表页_子类和商品列表交互效果_子类_09

已经有这个访问数据的方法,下一步就是调用我们的方法

Flutter移动电商实战 --(33)列表页_子类和商品列表交互效果_flutter 项目实战_10

数据展示:

Flutter移动电商实战 --(33)列表页_子类和商品列表交互效果_子类_11

最终代码:

provide/child_category.dart

import 'package:flutter/material.dart';
import '../model/category.dart';

class ChildCategory with ChangeNotifier{
 List<BxMallSubDto> childCategoryList=[];
 int childIndex=0;//子类高亮索引
 String categoryId='4';//大类ID 白酒的id 默认为4
  //大类切换逻辑
  getChildCategory(List<BxMallSubDto> list,String id){
    childIndex=0;//每次点击大类,小类的索引都要清空掉
    categoryId=id;
    BxMallSubDto all=BxMallSubDto();
    all.mallCategoryId="00";
    all.mallCategoryId="00";
    all.comments="null";
    all.mallSubName='全部';
    childCategoryList=[all];
    //childCategoryList=list;
    childCategoryList.addAll(list);
    notifyListeners();//监听
  }
  //改变子类索引,indexs是从哪里来的呢?从我们具体的类中进行传递
  changeChildIndex(index){
    childIndex=index;//把传递过来的index赋值给我们的childIndex
    notifyListeners();//通知
  }
}

category_page.dart

import 'package:flutter/material.dart';
import '../service/service_method.dart';
import 'dart:convert';
import '../model/category.dart';
import '../model/categoryGoodsList.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provide/provide.dart';
import '../provide/child_category.dart';
import '../provide/category_goods_list.dart';

class CategoryPage extends StatefulWidget {
  @override
  _CategoryPageState createState() => _CategoryPageState();
}

class _CategoryPageState extends State<CategoryPage> {
  @override
  Widget build(BuildContext context) {
    //_getCategory();
    return Scaffold(
      appBar: AppBar(title: Text('商品分类'),),
      body: Container(
        child: Row(
          children: <Widget>[
            LeftCategoryNav(),
            Column(
              children: <Widget>[
                RightCategoryNav(),
                CategoryGoodsList()
              ],
            )
          ],
        ),
      ),
    );
  }

 
}

//左侧大类导航
class LeftCategoryNav extends StatefulWidget {
  @override
  _LeftCategoryNavState createState() => _LeftCategoryNavState();
}

class _LeftCategoryNavState extends State<LeftCategoryNav> {
  List list=[];
  var listIndex=0;
  @override
  void initState() { 
    super.initState();
    _getCategory();//请求接口的数据
    _getGoodsList();//参数是可选的默认是4 所以这里可以不用传值
  }
  @override
  Widget build(BuildContext context) {
    return Container(
      width: ScreenUtil().setWidth(180),
      decoration: BoxDecoration(
        border: Border(
          right: BorderSide(width:1.0,color: Colors.black12),//有边框
        )
      ),
      child: ListView.builder(
        itemCount: list.length,
        itemBuilder: (contex,index){
          return _leftInkWell(index);
        },
      ),
    );
  }

  Widget _leftInkWell(int index){
    bool isClick=false;
    isClick=(index==listIndex)?true:false;
    return InkWell(
      onTap: (){
        setState(() {
         listIndex=index; 
        });
        var childList=list[index].bxMallSubDto;//当前大类的子类的列表
        var categoryId=list[index].mallCategoryId;//大类的id
        Provide.value<ChildCategory>(context).getChildCategory(childList,categoryId);
        _getGoodsList(categoryId:categoryId);
      },
      child: Container(
        height: ScreenUtil().setHeight(100),
        padding: EdgeInsets.only(left:10.0,top:10.0),
        decoration: BoxDecoration(
          color: isClick?Color.fromRGBO(236, 236, 236, 1.0): Colors.white,
          border: Border(
            bottom: BorderSide(width: 1.0,color: Colors.black12)
          )
        ),
        child: Text(
          list[index].mallCategoryName,
          style: TextStyle(fontSize: ScreenUtil().setSp(28)),//设置字体大小,为了兼容使用setSp
        ),
      ),
    );
  }
   void _getCategory() async{
    await request('getCategory').then((val){
      var data=json.decode(val.toString());
      //print(data);
      CategoryModel category= CategoryModel.fromJson(data);
      setState(() {
       list=category.data; 
      });
      Provide.value<ChildCategory>(context).getChildCategory(list[0].bxMallSubDto,list[0].mallCategoryId);
    });
  }

  void _getGoodsList({String categoryId}) {
    var data={
      'categoryId':categoryId==null?'4':categoryId,//白酒的默认类别
      'categorySubId':"",
      'page':1
    };
    request('getMallGoods',formData: data).then((val){
      var data=json.decode(val.toString());
      CategoryGoodsListModel goodsList=CategoryGoodsListModel.fromJson(data);//这样就从json'转换成了model类
      //print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>:${goodsList.data[0].goodsName}');
      // setState(() {
      //  list=goodsList.data; 
      // });
      Provide.value<CategoryGoodsListProvide>(context).getGoodsList(goodsList.data);
    });
  }
}

class RightCategoryNav extends StatefulWidget {
  @override
  _RightCategoryNavState createState() => _RightCategoryNavState();
}

class _RightCategoryNavState extends State<RightCategoryNav> {
  //List list = ['名酒','宝丰','北京二锅头','舍得','五粮液','茅台','散白'];
  @override
  Widget build(BuildContext context) {
    return Provide<ChildCategory>(
      builder: (context,child,childCategory){
        return  Container(
          height: ScreenUtil().setHeight(80),
          width: ScreenUtil().setWidth(570),//总的宽度是750 -180
          decoration: BoxDecoration(
            color: Colors.white,//白色背景
            border: Border(
              bottom: BorderSide(width: 1.0,color: Colors.black12)//边界线
            )
          ),
          child: ListView.builder(
            scrollDirection: Axis.horizontal,
            itemCount: childCategory.childCategoryList.length,
            itemBuilder: (context,index){
              return _rightInkWell(index,childCategory.childCategoryList[index]);
            },
          ),
        );
      }
    );
  }

  Widget _rightInkWell(int index,BxMallSubDto item){
    bool isClick=false;
    isClick=(index==Provide.value<ChildCategory>(context).childIndex)?true:false;

    return InkWell(
      onTap: (){
        Provide.value<ChildCategory>(context).changeChildIndex(index);
        _getGoodsList(item.mallSubId);
      },//事件留空
      child: Container(//什么都加一个container,这样好布局
        padding: EdgeInsets.fromLTRB(5.0, 10.0, 5.0, 10.0),//上下是10 左右是5.0
        child: Text(
          item.mallSubName,
          style:TextStyle(
            fontSize: ScreenUtil().setSp(28),
            color: isClick?Colors.pink:Colors.black
          ),
        ),
      ),
    );
  }
  void _getGoodsList(String categorySubId) {
    var data={
      'categoryId':Provide.value<ChildCategory>(context).categoryId,//大类ID
      'categorySubId':categorySubId,
      'page':1
    };
    request('getMallGoods',formData: data).then((val){
      var data=json.decode(val.toString());
      CategoryGoodsListModel goodsList=CategoryGoodsListModel.fromJson(data);//这样就从json'转换成了model类
      Provide.value<CategoryGoodsListProvide>(context).getGoodsList(goodsList.data);
    });
  }
}

//商品列表 ,可以上拉加载
class CategoryGoodsList extends StatefulWidget {
  @override
  _CategoryGoodsListState createState() => _CategoryGoodsListState();
}

class _CategoryGoodsListState extends State<CategoryGoodsList> {

  @override
  void initState() {
    //_getGoodsList();
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    return Provide<CategoryGoodsListProvide>(
      builder: (context,child,data){
        return  Expanded(
          child: Container(
            width: ScreenUtil().setWidth(570),
            //height: ScreenUtil().setHeight(974),
            child: ListView.builder(
              itemCount: data.goodsList.length,
              itemBuilder: (contex,index){
                return _listWidget(data.goodsList,index);
              },
            ),
          ),
        );
      },
    );
    
   
  }
  

  Widget _goodsImage(List newList,index){
    return Container(
      width: ScreenUtil().setWidth(200),//设置200的宽度 限制
      child: Image.network(newList[index].image),
    );
  }
  Widget _goodsName(List newList,index){
    return Container(
      padding: EdgeInsets.all(5.0),//上下左右都是5.0的内边距
      width: ScreenUtil().setWidth(370),//370是一个大约的值
      child: Text(
        newList[index].goodsName,
        maxLines: 2,//最多显示2行内容
        overflow: TextOverflow.ellipsis,
        style: TextStyle(fontSize: ScreenUtil().setSp(28)),//字体大小
      ),
    );
  }

  Widget _goodsPrice(List newList,index){
    return Container(
      margin: EdgeInsets.only(top:20.0),//和上面的外间距
      width: ScreenUtil().setWidth(370),//370是一个大约的值
      child: Row(
        children: <Widget>[
          Text(
            '价格¥${newList[index].presentPrice}',
            style: TextStyle(color: Colors.pink,fontSize: ScreenUtil().setSp(30)),
          ),
          Text(
            '价格¥${newList[index].oriPrice}',
            style: TextStyle(
              color: Colors.black26,
              decoration: TextDecoration.lineThrough
            ),//删除线的样式
          )
        ],
      ),
    );
  }

  Widget _listWidget(List newList,int index){
    return InkWell(
      onTap: (){},
      child: Container(
        padding: EdgeInsets.only(top:5.0,bottom:5.0),
        decoration: BoxDecoration(
          color: Colors.white,
          border: Border(
            bottom: BorderSide(width: 1.0,color: Colors.black12)
          )
        ),
        child: Row(
          children: <Widget>[
            _goodsImage(newList,index),
            Column(
              children: <Widget>[
                _goodsName(newList,index),
                _goodsPrice(newList,index)
              ],
            )
          ],
        ),
      ),
    );
  }
}

.