zoukankan      html  css  js  c++  java
  • 12 Flutter仿京东商城项目 商品列表页面请求数据、封装Loading Widget、上拉分页加载更多

    ProductList.dart

    import 'package:flutter/material.dart';
    import '../services/ScreenAdaper.dart';
    import '../config/Config.dart';
    import 'package:dio/dio.dart';
    import '../model/ProductModel.dart';
    import '../widget/LoadingWidget.dart';
    
    class ProductListPage extends StatefulWidget {
      Map arguments;
      ProductListPage({Key key, this.arguments}) : super(key: key);
    
      _ProductListPageState createState() => _ProductListPageState();
    }
    
    class _ProductListPageState extends State<ProductListPage> {
      //通过事件打开侧边栏,需要全局声明一下:
      final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
      //配置下拉加载更多:
      ScrollController _scrollController = ScrollController();
      //分页:
      int _page = 1;
      //每一页有多少条数据:
      int _pageSize = 10;
      //分页:
      List _productList = [];
      //排序:
      String _sort = "";
      //解决重复请求的问题:
      bool flag = true;
    
      //是否有数据:
      bool _hasMore = true;
    
      //初始化的时候获取的生命周期函数:
      @override
      void initState() {
        super.initState();
        _getProductListData();
        //监听滚动条滚动事件:
        _scrollController.addListener(() {
          // _scrollController.position.pixels //获取滚动条滚动高度
          // _scrollController.position.maxScrollExtent //获取页面滚动高度:
          if (_scrollController.position.pixels >
              _scrollController.position.maxScrollExtent - 20) {
            if (this.flag&&this._hasMore) {
              _getProductListData();
            }
          }
        });
      }
    
      //获取商品列表的数据:
      _getProductListData() async {
        setState(() {
          this.flag = false;
        });
        var api =
            '${Config.domain}api/plist?cid=${widget.arguments["cid"]}&page=${_page}&sort=${this._sort}&pageSize=${_pageSize}';
        var result = await Dio().get(api);
        var productList = ProductModel.fromJson(result.data);
        print(productList.result);
    
        if (productList.result.length < this._pageSize) {
          setState(() {
            this._productList.addAll(productList.result);
            this._hasMore = false;
            this.flag = true;
            // this._productList = productList.result;
          });
        } else {
          setState(() {
            this._productList.addAll(productList.result);
            this._page++;
            this.flag = true;
            // this._productList = productList.result;
          });
        }
      }
      //显示加载中的圈圈:
      Widget _showMore(index){
        if(this._hasMore){
          return (index == this._productList.length - 1)? LoadingWidget() : Text('');
        }else{
          return (index == this._productList.length - 1)? Text("---暂无其他数据了--") : Text('');
        }
      }
    
      //商品列表:
      Widget _productListWidget() {
        if (this._productList.length > 0) {
          return Container(
            padding: EdgeInsets.all(10),
            margin: EdgeInsets.only(top: ScreenAdaper.height(80)),
            child: ListView.builder(
              controller: _scrollController,
              itemBuilder: (context, index) {
                //处理图片:
                String pic = this._productList[index].pic;
                pic = Config.domain + pic.replaceAll('\', '/');
                //获得每一个元素:
                return Column(
                  children: <Widget>[
                    Row(
                      children: <Widget>[
                        Container(
                           ScreenAdaper.width(180),
                          height: ScreenAdaper.height(180),
                          child: Image.network("${pic}", fit: BoxFit.cover),
                        ),
                        Expanded(
                          flex: 1,
                          child: Container(
                            height: ScreenAdaper.height(180),
                            margin: EdgeInsets.only(left: 10),
                            // color: Colors.red,
                            child: Column(
                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: <Widget>[
                                Text(
                                  "${this._productList[index].title}",
                                  maxLines: 2,
                                  overflow: TextOverflow.ellipsis,
                                ),
                                Row(
                                  children: <Widget>[
                                    Container(
                                      height: ScreenAdaper.height(36),
                                      margin: EdgeInsets.only(right: 10),
                                      padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
                                      //注意:如果Container里面加上decoration属性,这个时候color属性必须放到BoxDecoration
                                      decoration: BoxDecoration(
                                        borderRadius: BorderRadius.circular(10),
                                        // color:Color.fromRGBO(230, 230, 230, 0.9)
                                      ),
                                      child: Text('4G'),
                                    ),
                                    Container(
                                      height: ScreenAdaper.height(36),
                                      margin: EdgeInsets.only(right: 10),
                                      padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
                                      //注意:如果Container里面加上decoration属性,这个时候color属性必须放到BoxDecoration
                                      decoration: BoxDecoration(
                                        borderRadius: BorderRadius.circular(10),
                                        // color:Color.fromRGBO(230, 230, 230, 0.3)
                                      ),
                                      child: Text('16G'),
                                    )
                                  ],
                                ),
                                Text("¥ ${this._productList[index].price}",
                                    style:
                                        TextStyle(color: Colors.red, fontSize: 16))
                              ],
                            ),
                          ),
                        )
                      ],
                    ),
                    Divider(
                      height: 20,
                    ),
                    this._showMore(index)
                  ],
                );
              },
              itemCount: this._productList.length,
            ),
          );
        } else {
          return LoadingWidget();
        }
      }
    
      //筛选导航:
      Widget _subHeaderWidget() {
        return Positioned(
          top: 0,
          height: ScreenAdaper.height(80),
           ScreenAdaper.width(750),
          child: Container(
            height: ScreenAdaper.height(80),
             ScreenAdaper.width(750),
            // color: Colors.red,
            decoration: BoxDecoration(
                border: Border(
                    bottom: BorderSide(
                         1, color: Color.fromRGBO(233, 233, 233, 0.9)))),
            child: Row(
              children: <Widget>[
                Expanded(
                  flex: 1,
                  child: InkWell(
                    child: Padding(
                      padding: EdgeInsets.fromLTRB(
                          0, ScreenAdaper.height(20), 0, ScreenAdaper.height(20)),
                      child: Text(
                        '综合',
                        textAlign: TextAlign.center,
                        style: TextStyle(color: Colors.red),
                      ),
                    ),
                    onTap: () {},
                  ),
                ),
                Expanded(
                  flex: 1,
                  child: InkWell(
                    child: Padding(
                      padding: EdgeInsets.fromLTRB(
                          0, ScreenAdaper.height(20), 0, ScreenAdaper.height(20)),
                      child: Text('销量', textAlign: TextAlign.center),
                    ),
                    onTap: () {},
                  ),
                ),
                Expanded(
                  flex: 1,
                  child: InkWell(
                    child: Padding(
                      padding: EdgeInsets.fromLTRB(
                          0, ScreenAdaper.height(20), 0, ScreenAdaper.height(20)),
                      child: Text('价格', textAlign: TextAlign.center),
                    ),
                    onTap: () {},
                  ),
                ),
                Expanded(
                  flex: 1,
                  child: InkWell(
                    child: Padding(
                      padding: EdgeInsets.fromLTRB(
                          0, ScreenAdaper.height(20), 0, ScreenAdaper.height(20)),
                      child: Text('筛选', textAlign: TextAlign.center),
                    ),
                    onTap: () {
                      _scaffoldKey.currentState.openEndDrawer();
                    },
                  ),
                )
              ],
            ),
          ),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        ScreenAdaper.init(context);
        return Scaffold(
          key: _scaffoldKey,
          appBar: AppBar(
            title: Text('商品列表'),
            actions: <Widget>[Text('')],
          ),
          endDrawer: Drawer(
            child: Container(
              child: Text('实现筛选功能'),
            ),
          ),
          // body: Text("${widget.arguments}"),
          body: Stack(
            children: <Widget>[_productListWidget(), _subHeaderWidget()],
          ),
        );
      }
    }

    Category.dart

    import 'package:flutter/material.dart';
    import '../../services/ScreenAdaper.dart';
    import '../../config/Config.dart';
    import 'package:dio/dio.dart';
    import '../../model/CateModel.dart';
    
    class CategoryPage extends StatefulWidget {
      CategoryPage({Key key}) : super(key: key);
    
      _CategoryPageState createState() => _CategoryPageState();
    }
    
    class _CategoryPageState extends State<CategoryPage>
        with AutomaticKeepAliveClientMixin {
      int _selectIndex = 0;
      List _leftCateList = [];
      List _rightCateList = [];
      @override
      // TODO: implement wantKeepAlive
      bool get wantKeepAlive => true;
      @override
      void initState() {
        super.initState();
        _getLeftCateData();
      }
    
      //左侧数据:
      _getLeftCateData() async {
        var api = '${Config.domain}api/pcate';
        var result = await Dio().get(api);
        var leftCateList = CateModel.fromJson(result.data);
        setState(() {
          this._leftCateList = leftCateList.result;
        });
        _getRightCateData(leftCateList.result[0].sId);
      }
    
      //右侧数据:
      _getRightCateData(pid) async {
        var api = '${Config.domain}api/pcate?pid=${pid}';
        var result = await Dio().get(api);
        var rightCateList = CateModel.fromJson(result.data);
        print(6666);
        setState(() {
          this._rightCateList = rightCateList.result;
        });
      }
    
      //左侧组件
      Widget _leftCateWidget(leftWidth) {
        if (this._leftCateList.length > 0) {
          return Container(
             leftWidth,
            height: double.infinity,
            // color: Colors.red,
            child: ListView.builder(
              itemCount: this._leftCateList.length,
              itemBuilder: (context, index) {
                return Column(
                  children: <Widget>[
                    InkWell(
                      onTap: () {
                        setState(() {
                          // setState(() {
                          _selectIndex = index;
                          this._getRightCateData(this._leftCateList[index].sId);
                        });
                        print(_selectIndex);
                      },
                      child: Container(
                         double.infinity,
                        height: ScreenAdaper.height(56),
                        padding: EdgeInsets.only(top: ScreenAdaper.height(24)),
                        child: Text("${this._leftCateList[index].title}",
                            textAlign: TextAlign.center),
                        color: _selectIndex == index
                            ? Color.fromRGBO(240, 246, 246, 0.9)
                            : Colors.white,
                      ),
                    ),
                    Divider(height: 1),
                  ],
                );
              },
            ),
          );
        } else {
          return Container(
             leftWidth,
            height: double.infinity,
          );
        }
      }
    
      //右侧组件:
      Widget _rightCateWidget(rightItemWidth, rightItemHeigth) {
        if (this._rightCateList.length > 0) {
          return Expanded(
            flex: 1,
            child: Container(
              padding: EdgeInsets.all(10),
              height: double.infinity,
              color: Color.fromRGBO(240, 246, 246, 0.9),
              // color: Colors.blue,
              child: GridView.builder(
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 3,
                    childAspectRatio: rightItemWidth / rightItemHeigth,
                    crossAxisSpacing: 10,
                    mainAxisSpacing: 10),
                itemCount: this._rightCateList.length,
                itemBuilder: (context, index) {
                  //处理图片:
                  String pic = this._rightCateList[index].pic;
                  pic = Config.domain + pic.replaceAll('\', '/');
                  return InkWell(
                      child: Container(
                        // padding: EdgeInsets.all(ScreenAdaper.width(20)),
                        child: Column(
                          children: <Widget>[
                            AspectRatio(
                              aspectRatio: 1 / 1,
                              child: Image.network("${pic}", fit: BoxFit.cover),
                            ),
                            Container(
                              height: ScreenAdaper.height(32),
                              child: Text("${this._rightCateList[index].title}"),
                            )
                          ],
                        ),
                      ),
                      onTap: (){
                        Navigator.pushNamed(context,'/productList',arguments: {
                          "cid":this._rightCateList[index].sId
                        });
                      },
    
                  );
                },
              ),
            ),
          );
        } else {
          return Expanded(
              flex: 1,
              child: Container(
                padding: EdgeInsets.all(10),
                height: double.infinity,
                color: Color.fromRGBO(240, 246, 246, 0.9),
                child: Text('加载中...'),
              ));
        }
      }
    
      Widget build(BuildContext context) {
        ScreenAdaper.init(context);
    
        //计算右侧GridView宽高比:
        var leftWidth = ScreenAdaper.getScreenWidth() / 4;
        //右侧宽高=总宽度-左侧宽度-Gridview外层元素左右的Padding值-GridView中间的间距
        var rightItemWidth =
            (ScreenAdaper.getScreenWidth() - leftWidth - 20 - 20) / 3;
        rightItemWidth = ScreenAdaper.width(rightItemWidth);
        var rightItemHeigth = rightItemWidth + ScreenAdaper.height(32);
    
        return Row(
          children: <Widget>[
            _leftCateWidget(leftWidth),
            _rightCateWidget(rightItemWidth, rightItemHeigth)
          ],
        );
      }
    }

  • 相关阅读:
    转:Ubuntu12.04编译VLC,在linux上运行
    samba 安装运行
    设计模式学习笔记 1.factory 模式
    python之字符串的拼接总结
    str函数之不同变量之间如何连接,外加浮点运算注意事项
    python的安装以及前景
    input函数的运用和注意 小知识点
    mysql基础篇(上篇)
    接口测试基本安全
    jmeter接口自动化测试
  • 原文地址:https://www.cnblogs.com/yiweiyihang/p/11420838.html
Copyright © 2011-2022 走看看