zoukankan      html  css  js  c++  java
  • Flutter实战视频-移动电商-34.列表页_小BUG的修复

    34.列表页_小BUG的修复

    当高粱酒的子类没有数据返回的时候就会报错。

    解决接口空数据报错的问题

    没有数据的时候,给用户一个友好的提示,

    我们没有数据的时候还要告诉用户,提示一下他没有数据,在我们的右侧列表的build方法内去判断

    友好提示展示效果:

    子类的id状态化

    状态管理里面,定义小类的变量,并根据传入的id根性赋值。这样我们在点击小类的时候,需要也传入小类的id

    这样我们在小类点击事件里面,传入小类的id就可以了

    测试程序

    点击小类进行测试

    最终代码:

    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
     String subId='';//小类ID
      //大类切换逻辑
      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,String id){
        childIndex=index;//把传递过来的index赋值给我们的childIndex
        subId=id;
        notifyListeners();//通知
      }
    }

    pages/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,item.mallSubId);
            _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类
          if(goodsList.data==null){
            Provide.value<CategoryGoodsListProvide>(context).getGoodsList([]);
          }else{
            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){
            if(data.goodsList.length>0){
                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);
                      },
                    ),
                  ),
                );
            }else{
              return Text('暂时没有数据');
            }
           
          },
        );
        
       
      }
      
    
      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)
                  ],
                )
              ],
            ),
          ),
        );
      }
    }
    category_page.dart
  • 相关阅读:
    自定义标签的作用
    自定义标签处理器类的生命周期
    自定义标签的执行过程
    自定义标签入门案例
    JSTL核心标签库详解
    JSTL标签(核心标准库)
    动作标签
    jsp标签
    EL表达式
    JSP学习案例--,竞猜游戏
  • 原文地址:https://www.cnblogs.com/wangjunwei/p/10721009.html
Copyright © 2011-2022 走看看