首页 > 其他分享 >flutter实现下拉刷新和加载更多

flutter实现下拉刷新和加载更多

时间:2023-04-10 16:01:37浏览次数:40  
标签:Text 刷新 list page ._ flutter 加载

问题背景

移动端日常开发过程中,下拉刷新和加载更多是很常见的功能点,现在一起看下flutter是如何实现下拉刷新和加载更多的。

问题分析

1、通过Dio框架获取网络请求

        var url = "http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=$_page";
        Response result = await Dio().get(url);
        var list = json.decode(result.data)["result"];

2、Flutter中提供了组件 RefreshIndicator用于下拉刷新 其基本的实现方法是在该组件添加onRefresh事件,当用户下拉刷新时会触发该事件,在该事件中可以用调用一个延时任务Future.delayed( ),在延时任务的回调中重新请求数据即可。

RefreshIndicator(
                  child: ListView.builder(
                    ......
                  ),
                  // 2、回调下拉刷新事件
                  onRefresh:this._onRefresh
              )

3、flutter中主要通过使用 ListView.builder( ) 添加控制器来实现上拉加载更多

ListView.builder(
                    // 上拉加载控制器
                    controller: _scrollController,
                    itemCount: this._list.length,
                    itemBuilder: (context,index){

                      Widget tip = Text("");
                      // 当渲染到最后一条数据时,加载动画提示
                      if(index == this._list.length-1){
                        tip = _getMoreWidget();
                      }
                      return Column(
                        children: <Widget>[
                          ListTile(
                              title:Text(
                                "${this._list[index]["title"]}",
                                maxLines:1,
                              )
                          ),
                          Divider(),
                          // 加载提示
                          tip
                        ],
                      );
                    },
                  ),

问题解决

上面分析了flutter实现下拉刷新和加载更多的关键环节,完整代码如下:

import 'dart:convert';

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

class Test extends StatefulWidget {
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {
    // 页数
    int _page = 1;
    // 页面数据列表
    List _list = [];
    // 标志位:是否有更多数据
    bool _hasMore = true;
    // 滚动控制器
    ScrollController _scrollController = new ScrollController();

    @override
    void initState() {
      super.initState();
      this._getData();
      // 监听滚动事件
      _scrollController.addListener((){
        if(_scrollController.position.pixels>_scrollController.position.maxScrollExtent-40){
          this._getData();
        }
      });
    }

    // 获取数据列表
    void _getData() async{
      if(this._hasMore){
        var url = "http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=$_page";
        Response result = await Dio().get(url);
        var list = json.decode(result.data)["result"];

        setState(() {
          // 拼接数据
          this._list.addAll(list);
          // 页数累加
          this._page++;
        });

        if(list.length<20){
          setState(() {
            // 关闭加载
            this._hasMore = false;
          });
        }
      }
    }

    // 下拉刷新
    Future<void> _onRefresh() async{
      print("下拉刷新");
      // 持续两秒
      await Future.delayed(Duration(milliseconds:2000),(){
        // 清空数据进行刷新
        this._list.clear();
        this._page = 1;
        this._getData();
      });
    }

    // 加载动画
    Widget _getMoreWidget() {
      // 如果还有数据
      if(this._hasMore){
        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: 1.0,
                )
              ],
            ),
          ),
        );
      }else{
        return Center(
          child: Text("...我是有底线的..."),
        );
      }
    }

    @override
    Widget build(BuildContext context) {
      return Container(
          child:Scaffold(
              appBar: AppBar(
                  title:Text("新闻列表")
              ),
              body:this._list.length==0?this._getMoreWidget():RefreshIndicator(
                  child: ListView.builder(
                    // 上拉加载控制器
                    controller: _scrollController,
                    itemCount: this._list.length,
                    itemBuilder: (context,index){

                      Widget tip = Text("");
                      // 当渲染到最后一条数据时,加载动画提示
                      if(index == this._list.length-1){
                        tip = _getMoreWidget();
                      }
                      return Column(
                        children: <Widget>[
                          ListTile(
                              title:Text(
                                "${this._list[index]["title"]}",
                                maxLines:1,
                              )
                          ),
                          Divider(),
                          // 加载提示
                          tip
                        ],
                      );
                    },
                  ),
                  // 下拉刷新事件
                  onRefresh:this._onRefresh
              )
          )
      );
    }
}

运行结果如下: 1681112606931.gif

问题总结

本文主要是介绍了flutter是如何实现下拉刷新和加载更多的,有兴趣的同学可以进一步深入研究。

标签:Text,刷新,list,page,._,flutter,加载
From: https://blog.51cto.com/baorant24/6181066

相关文章

  • vue实现路由懒加载(异步加载)及组件懒加载(异步加载)的方式
    转自:槐序之夏:https://blog.csdn.net/qq_42403643/article/details/129264032一、为什么要使用路由懒加载为给客户更好的客户体验,首屏组件加载速度更快一些,解决白屏问题。二、定义懒加载简单来说就是延迟加载或按需加载,即在需要的时候的时候进行加载。三、使用常用的懒加......
  • 关于vue2老项目的打包优化,实现首屏加载速度提升
    分析项目代码体积yarnaddwebpack-bundle-analyzer在webpack.dev.conf.js中配置constBundleAnalyzerPlugin=require('webpack-bundle-analyzer').BundleAnalyzerPluginplugins:[newBundleAnalyzerPlugin(),//代码体积分析插件......]执行yarnrundev或......
  • nginx更新静态页面客户端缓存不刷新问题
    问题描述:频繁部署静态资源,nginx自带缓存未刷新通过ftp/sftp上传到nginx的静态页(尤其是打包好的单页应用),有可能遇到客户端缓存不刷新的问题,即使重启nginx都无效客户端浏览器也有缓存,一般关闭进程(手机清理,注意某些app光按返回键退回桌面是不会结束进程的),强制刷新网页等方法可以......
  • 一统天下 flutter - widget 列表类: ExpansionTile - 列表项(可展开)
    一统天下flutterhttps://github.com/webabcd/flutter_demo作者webabcd一统天下flutter-widget列表类:ExpansionTile-列表项(可展开)示例如下:lib\widget\list\expansion_tile.dart/**ExpansionTile-列表项(可展开)*/import'package:flutter/material.dart'......
  • 一统天下 flutter - widget 状态管理: 状态管理 - 自定义 controller
    一统天下flutterhttps://github.com/webabcd/flutter_demo作者webabcd一统天下flutter-widget状态管理:状态管理-自定义controller示例如下:lib\state\controller.dart/**状态管理-自定义controller**为自定义组件指定一个自定义controller后,就可......
  • 一统天下 flutter - 插件: flutter 与 android 原生之间的数据通信
    一统天下flutterhttps://github.com/webabcd/flutter_demo作者webabcd一统天下flutter-插件:flutter与android原生之间的数据通信示例如下:lib\plugin\plugin.dart/**插件*本例用于演示flutter与android/ios原生之间的数据通信**一、android插件......
  • SpringMVC中使用引入jquery不能加载页面
    今天在学习springMVC的json数据绑定时,需要使用到jquery发送ajax请求。但是当我通过是<script>标签引入了jquery.js。但是当我访问该jsp的时候就是不显示页面的内容我一直以为时SpringMVC的servelt拦截器拦截了静态资源,但是我过滤了静态资源还是不显示。后来才发现,我把<script......
  • 百度高德地图JS-API学习手记:地图基本设置与省市区数据加载
    无论是百度还是高德地图开发,还是高德地图开发。官方的给的案例启示很多,copy再修改下,就完成了https://lbs.amap.com/api/javascript-api/summary  http://lbsyun.baidu.com/index.php?title=jspopular3.0这个大致看一下,我想。有点GIS基础都能完成地图开发。个人认为百度的文档......
  • 解决Flutter_Boost,在Android Studio 出现“Cannot resolve symbol” 的问题
    今天在调试的时候,Android Studio报了一个莫名其妙的错误Cannot resolve symbol'R'让人不知所措,怎么会出现 Cannot resolve symbol 这种错误呢?下面给大家分享Android Studio 出现“Cannot resolve symbol”解决方案,需要的朋友可以参考下一:AndroidStudio无法识别同......
  • 移动端技术:如何提高网站的加载速度?
    ​ 在移动互联网时代,网站的加载速度对于用户体验和SEO排名都至关重要。因此,如何提高网站的加载速度成为了每个网站开发者和运营者必须面对的问题。本文将从以下几个方面介绍如何提高网站的加载速度。一、优化图片图片是网站中占用带宽最大的元素之一,因此优化图片是提高网站加载......