替换掉flutter第三方的上拉刷新,下拉加载组件

前言

由于flutter_easyrefresh有一点点的小bug,才做的此案例,对于一个项目而言,用户体验很重要
在哔哩哔哩中使用的上拉刷新跟这个是一样的
本案例是以一页数据可以请求20条
首先做一个上拉刷新,下拉加载,这两句话是什么意思
上拉刷新:,下拉的时候,将当前有限的屏幕中显示的数据替换当
这个提替换掉不是单纯的直接赋值掉,而是将数据插入在当前显示的列表当中
并且数据加载完毕之后提示用户
为什么要这么做?
试想一个场景,如果你将数据全部替换掉了,用户要看之前的浏览记录呢?
下拉下载:下拉的时候将数据加载到有限的屏幕显示
将请求的数据添加在末尾,没有数据了提示用户
 不管是上拉刷新和下拉加载,都要判断是否为最后一页


  需要的依赖

#网络请求  
dio: any
#提示框
fluttertoast: ^8.0.4

 代码

import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';

class LoadDataPage extends StatefulWidget {
  const LoadDataPage({Key? key}) : super(key: key);
  @override
  _LoadDataPageState createState() => _LoadDataPageState();
}

class _LoadDataPageState extends State<LoadDataPage> {
  ScrollController _controller = new ScrollController();

  //数据存放的容器
  List data = [];

  //当前请求数据的页数
  int pageIndex = 1;

  //是否是最后一页数据
  bool isHasMore = true;

  @override
  void initState() {
    dropDownLoad();
    //监听长度的变化
    _controller.addListener(() {
      print("ListView长度滚动的距离" + _controller.position.pixels.toString());
      print("ListView占屏幕的总距离" + _controller.position.maxScrollExtent.toString());
      if (_controller.position.pixels > _controller.position.maxScrollExtent-40) {
        setState(() {
          pageIndex++;
          dropDownLoad();
        });
      }
    });
    super.initState();
  }

  //请求数据
  Future<List> requestData()async{
    final api = "http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=${pageIndex}";
    Response response = await Dio().get(api);
    return json.decode(response.data)["result"];
  }

  // 下拉加载
  Future dropDownLoad() async {
    if (isHasMore) {
      List list = await requestData();
      //小于20条数据说明是最后一页了
      if (list.length < 20) {
        setState(() {
          isHasMore = false;
          data.addAll(list);
        });
      }else{
        setState(() {
          data.addAll(list);
        });
      }
      print(data.toString() + "]]]]");
    }
  }

  //上拉刷新
  Future<void> _onRefresh()async{
    await Future.delayed(Duration(seconds: 1), ()async{
      pageIndex++;
      List list = await requestData();
      //如果请求到的数据是最后一页
      if(list.length<20){
        Fluttertoast.showToast(msg: "无再多的数据",gravity: ToastGravity.TOP);
      }else{
        data.insertAll(0, list);
        setState(() {});
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    final appAar = AppBar(
      title: Text("使用flutter组件实现下拉刷新"),
    );

    return Scaffold(
      appBar: appAar,
      body: data.length > 0
          ? RefreshIndicator(
            onRefresh:_onRefresh,
            child: ListView.builder(
                controller: _controller,
                itemCount: data.length,
                itemBuilder: (context, index) {
                  //如果是最后一条数据
                  print(data.length == index);
                  //data的length是0-19,index是1-20
                  if(this.data.length-1 == index){
                    print("到底了=====================================");
                    return Column(
                      children: [
                        ListTile(
                          subtitle: Text(data[index]["aid"]),
                          title: Text(data[index]["title"]),
                        ),
                        Divider(),
                        _getMoreWidget(this.isHasMore),
                      ],
                    );
                  }else{
                    return Column(
                      children: [
                        ListTile(
                          subtitle: Text(data[index]["aid"]),
                          title: Text(data[index]["title"]),
                        ),
                        Divider(),
                      ],
                    );
                  }
                }),
          )
          : Center(child: CircularProgressIndicator()),
    );
  }

  //加载到底部的圈圈
  Widget _getMoreWidget(bool isData) {
    if(isData){
      return Center(
        child: Padding(
          padding: EdgeInsets.all(10.0),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Text(
                '加载中...',
                style: TextStyle(fontSize: 16.0),
              ),
              CircularProgressIndicator(
                strokeWidth: 3.0,
                color: Colors.pinkAccent,
              )
            ],
          ),
        ),
      );
    }else{
      return Center(child: Text("数据到底了"));
    }
  }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值