zoukankan      html  css  js  c++  java
  • Flutter实战视频-移动电商-31.列表页_列表切换交互制作

    31.列表页_列表切换交互制作

    博客地址:https://jspang.com/post/FlutterShop.html#toc-c42

     点击左侧的大类右边的小类也跟着变化

    新建provide

    要改变哪里就建哪里的provide,我们现在要改变的是右边的商品列表的数组。

    category_goods_list.dart

    这样我们的provide类就做好了

    做好的provide类放到main.dart中注册

    这一步叫做 把状态放入顶层

    category_page.dart修改

    _getGoodsList方法整体移动到左侧的大类

    我们把他移动到了这里

    方法移动过来以后,我们要接受一个参数类别id,这个类别是可选的,可选的参数用{}括起来

    再判断传入的参数是否有值,如果有值就用这个值,如果没有值就用默认的白酒的分类是4

    引入provide更改右侧的列表数据

    import '../provide/category_goods_list.dart';

    这个时候我们会发现我们传入list的值有错。

    实际上我们的CategoryGoodsListModel类里面的data才是我们要传入的列表值 List<CategoryListData>

    所以这里我们要用.data的形式

    修改我们的右侧列表类

    list没有用,已经换成了provide的状态管理。这里删除掉就可以了。

    我们要在container的外层包括一层provide才可以去使用状态管理。

    外层包括Provide,builder里面三个参数,1:上下文对象 2:child 3:就是我们的数据了

    所有list的地方都要换成newList

    使用我们改编自状态的方法:_getGoodsList

    在我们左侧大类的onTap事件里面去调用这个小类数据的方法

    展示效果

    点击后右侧出现了数据

    刚进入页面的时候调用一次加载右侧列表的数据

    默认记载白酒的子类数据

    最终代码

    lib/provide/category_goods_list.dart

    import 'package:flutter/material.dart';
    import '../model/categoryGoodsList.dart';
    
    class CategoryGoodsListProvide with ChangeNotifier{
     List<CategoryListData> goodsList=[];
     //点击大类时候更换商品列表
     getGoodsList(List<CategoryListData> list){
       goodsList=list;
       notifyListeners();
     }
    }

    main.dart

    import 'package:flutter/material.dart';
    import './pages/index_page.dart';
    import 'package:provide/provide.dart';
    import './provide/counter.dart';
    import './provide/child_category.dart';
    import './provide/category_goods_list.dart';
    
    
    void main(){
     var counter=Counter();
     var childCategory=ChildCategory();
     var categoryGoodsListProvide=CategoryGoodsListProvide();
     var providers=Providers();
     //注册 依赖
     providers
     ..provide(Provider<Counter>.value(counter))
     ..provide(Provider<CategoryGoodsListProvide>.value(categoryGoodsListProvide))
     ..provide(Provider<ChildCategory>.value(childCategory)); 
      runApp(ProviderNode(child: MyApp(),providers: providers,));
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(
          child:MaterialApp(
            title:'百姓生活+',
            debugShowCheckedModeBanner: false,
            theme: ThemeData(
              primaryColor: Colors.pink
            ),
            home: IndexPage(),
          )
        );
      }
    }
    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);
            _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);
        });
      }
    
      void _getGoodsList({String categoryId}) async {
        var data={
          'categoryId':categoryId==null?'4':categoryId,//白酒的默认类别
          'CategorySubId':"",
          'page':1
        };
        await 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(childCategory.childCategoryList[index]);
                },
              ),
            );
          }
        );
      }
    
      Widget _rightInkWell(BxMallSubDto item){
        return InkWell(
          onTap: (){},//事件留空
          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)),
            ),
          ),
        );
      }
    }
    
    //商品列表 ,可以上拉加载
    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  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)
                  ],
                )
              ],
            ),
          ),
        );
      }
    }
    category_page.dart
  • 相关阅读:
    也谈用反射实现Enum→String映射:一种重视性能的方法【转载】
    C#对象的浅拷贝,深拷贝【转载】
    int转byte[],byte[]转int
    TF31003:您的用户帐户没有连接到 Team Foundation Server 的权限
    关于枚举的双语显示问题
    浅析C#深拷贝与浅拷贝
    反射枚举变量
    C#路径/文件/目录/I/O常见操作汇总(二)
    【转】正确理解ThreadLocal
    【转】JSP的九个隐含对象
  • 原文地址:https://www.cnblogs.com/wangjunwei/p/10704716.html
Copyright © 2011-2022 走看看