Flutter-防京东商城项目-获取商品列表数据和上拉加载-12

一直觉得自己写的不是技术,而是情怀,一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的,希望我的这条路能让你们少走弯路,希望我能帮你们抹去知识的蒙尘,希望我能帮你们理清知识的脉络,希望未来技术之巅上有你们也有我。

代码文档

Flutter防京东商城源码(1-10)链接

Flutter防京东商城源码(11-20)链接

Flutter防京东商城源码(21-30)链接

Flutter防京东商城源码(31-46)链接

第一部 加载网络数据效果:
请添加图片描述
第二部分 上拉加载更多数据效果:
请添加图片描述

本章学习目标:
1.数据用之前写好的productModel。
2.封装上拉加载控件

本章分两部分来做,首先先获取数据,数据赋值给UI控件,第二部分做上拉加载更多。然后跟着出现的bug逐步完善。

第一部分

第一步:封装上拉加载控件

在这里插入图片描述

LoadingWidget 源码

import 'package:flutter/material.dart';

class LoadingWidget extends StatelessWidget {
  const LoadingWidget({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return  Center(
      child: Padding(
        padding: EdgeInsets.all(10.0),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            CircularProgressIndicator(
              strokeWidth: 1.0,
            ),Text(
              '加载中...',
              style: TextStyle(fontSize: 16.0),
            )
          ],
        ),
      ),
    );;
  }
}

第二步:回到productList.dart文件

import 'package:flutter_app/widget/LoadingWidget.dart';
import 'package:dio/dio.dart';
import '../config/Config.dart';
import '../model/ProductModel.dart';

新建属性

//数据
List _productList = [];
//页数 用于请求
int _page = 1;
//请求一页返回的个数  限制8个
int _pageSize=8;
/*
排序:价格升序 sort=price_1 价格降序 sort=price_-1  销量升序 sort=salecount_1 销量降序 sort=salecount_-1
*/
String _sort = "";

编写获取网络数据的方法

//获取商品列表的数据
_getProductListData() async {
  var api =
      '${Config.domain}api/plist?cid=${widget.arguments["cid"]}&page=${this._page}&sort=${this._sort}&pageSize=${this._pageSize}';
  var result = await Dio().get(api);
  //获取数据后存储到模型里面
  var productList = new ProductModel.fromJson(result.data);
  //合并数据
  setState(() {
    this._productList.addAll(productList.result);//合并数据
  });

}

进入控制器调用网络数据的方法

@override
void initState() {
  super.initState();
  _getProductListData();
}

在_productListWidget方法的最外面添加判断用于显示加载控件

if (this._productList.length > 0) {
//抽取 把之前的代码写在里面
} else {
  //加载中
  return LoadingWidget();
}

修改显示数据的地方

//处理图片
String pic=this._productList[index].pic;
pic=Config.domain+pic.replaceAll('\\', '/');

 "${pic}",

在这里插入图片描述
文本

"${this._productList[index].title}",

在这里插入图片描述
富文本

"¥${this._productList[index].price}",

在这里插入图片描述
数组个数

itemCount: this._productList.length,

在这里插入图片描述
到这里显示数据已经OK了 下面是上拉加载更多

第二部分

1.写在_ProductListPageState里面

//用于上拉分页  用于上拉加载更多用的
ScrollController _scrollController = ScrollController(); //listview 的控制器

在这里插入图片描述

2.监听接近底部的时候调用获取网络数据的方法 写在 initState方法里面

在这里插入图片描述

@override
void initState() {
  super.initState();
  _getProductListData();

  //监听滚动条滚动事件
  _scrollController.addListener((){
    //_scrollController.position.pixels //获取滚动条滚动的高度
    //_scrollController.position.maxScrollExtent  //获取页面高度
    if(_scrollController.position.pixels>_scrollController.position.maxScrollExtent-20){
        _getProductListData();
    }
  });
}

3.添加监听控制器

controller: _scrollController,

编写地方提示
在这里插入图片描述
4.获取数据成功页数递增一

this._page++;//页数递增1

在这里插入图片描述

运行

添加加载中下面有一个菊花动画,写一个方法

//显示加载中的圈圈
Widget _showMore(index){
  return (index==this._productList.length-1)?LoadingWidget():Text("");
}

1.这句话写在 Divider(height: 20),的下面 自己搜索一下
注意 Divider(height: 20) 记得后面加逗号不然会报错。

_showMore(index)//这句话放在底部是用于显示  菊花  或者  我是有底线的

BUG

现在有个BUG 上拉加载发现数据重复加载,新建属性falg

//解决上拉重复请求的问题  加载的时候不能进来重复获取数据  造成重复加载
bool flag=true; 

2.写在if(_scrollController.position.pixels>_scrollController.position.maxScrollExtent-20){里面 搜索一下
替换 _getProductListData(); 其实就是外面包裹一个if判断

//加载的时候不能进来重复获取数据  造成重复加载
if(this.flag){ _getProductListData(); }

3.写在获取网络数据的方法里面 进来就锁住他 _getProductListData() async {写在这里下面

setState(() {
  //进来设置为false  不能重复加载
  this.flag=false;
});

在这里插入图片描述

4.写在 this._page++;//页数递增1 下面搜搜一下

this.flag=true;//加载数据完成 设置为true 加载上拉加载数据

在这里插入图片描述

运行

BUG

现在有一个BUG,没有数据的时候最底部有一值菊花在转(可以加载就有菊花转,没有数据的时候就显示我是有底线的)

1.创建一个属性

//是否有数据  有数据显示圈圈加载   无就显示我是有底线的
bool _hasMore=true;

2.加载数据时增加多一个判断this._hasMore

if(this.flag && this._hasMore){
  _getProductListData();
}

在这里插入图片描述

3.合并数据下面修改一下 var productList = new ProductModel.fromJson(result.data); 这句话下面 搜索一下

//加载回来的数据不够一页  显示我是有底线的
if(productList.result.length<this._pageSize){
  setState(() {
    this._productList.addAll(productList.result);//合并数据
    this._hasMore=false;//数据到底部  设置为false 用于显示我是有底线的
    this.flag=true;//加载数据完成 设置为true 加载上拉加载数据
  });
}else{
  setState(() {
    this._productList.addAll(productList.result);//合并数据
    this._page++;//页数递增1
    this.flag=true;//加载数据完成 设置为true 加载上拉加载数据
  });
}

4.修改整个方法

//显示加载中的圈圈
Widget _showMore(index){
  if(this._hasMore){ //有数据就显示   加载的菊花
    return (index==this._productList.length-1)?LoadingWidget():Text("");
  }else{ //没有数据显示我是有底线的
    return (index==this._productList.length-1)?Text("--我是有底线的--"):Text("");;
  }
}

运行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冯汉栩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值