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


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

    获取右侧下面的列表信息,即要传递大类的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

    大类id Provide化

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

    category_page.dart

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

    分别传入我们的大类id

    这我们去掉async和await修饰符

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

    复制到 _rightInkWell方法下面

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

    数据展示:

    最终代码:

    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(
           ScreenUtil().setWidth(180),
          decoration: BoxDecoration(
            border: Border(
              right: BorderSide(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( 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),
               ScreenUtil().setWidth(570),//总的宽度是750 -180
              decoration: BoxDecoration(
                color: Colors.white,//白色背景
                border: Border(
                  bottom: BorderSide( 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(
                 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(
           ScreenUtil().setWidth(200),//设置200的宽度 限制
          child: Image.network(newList[index].image),
        );
      }
      Widget _goodsName(List newList,index){
        return Container(
          padding: EdgeInsets.all(5.0),//上下左右都是5.0的内边距
           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),//和上面的外间距
           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( 1.0,color: Colors.black12)
              )
            ),
            child: Row(
              children: <Widget>[
                _goodsImage(newList,index),
                Column(
                  children: <Widget>[
                    _goodsName(newList,index),
                    _goodsPrice(newList,index)
                  ],
                )
              ],
            ),
          ),
        );
      }
    }

    .

  • 相关阅读:
    凤凰网面试经历——钢管舞也算精英文化吗
    立此为证:豆瓣要做电影数字发行了(2010818)
    Officially GoldenGate was purchased by oracle in October 1, 2009
    11gR2新特性:Heavy swapping observed on system in last 5 mins.
    Oracle BMW Racing sailing vessel帆船图
    Know more about CBO Index Cost
    Samsung Epic 4G 图文介绍
    Oracle Exalogic X22 HalfRack DiagramExaloic半配图
    Java 编程下线程的生命周期
    Android 编程组件Fragments 的生命周期与 Activity 的生命周期之间的关系
  • 原文地址:https://www.cnblogs.com/crazycode2/p/11442623.html
Copyright © 2020-2023  润新知