本文实例为大家分享了Flutter实现下拉刷新和上拉加载更多的具体代码,供大家参考,具体内容如下

效果

下拉刷新

如果实现下拉刷新,必须借助RefreshIndicator,在listview外面包裹一层RefreshIndicator,然后在RefreshIndicator里面实现onRefresh方法。

body: movieList.length == 0
          ? new Center(child: new CircularProgressIndicator())
          : new RefreshIndicator(
              color: const Color(0xFF4483f6),
              //下拉刷新
              child: ListView.builder(
                itemCount: movieList.length   1,
                itemBuilder: (context, index) {
                  if (index == movieList.length) {
                    return _buildProgressMoreIndicator();
                  } else {
                    return renderRow(index, context);
                  }
                },
                controller: _controller, //指明控制器加载更多使用
              ),
              onRefresh: _pullToRefresh,
            ),

onRefresh方法的实现_pullToRefresh,注意这里必须使用async 不然报错

 /**
   * 下拉刷新,必须异步async不然会报错
   */
  Future _pullToRefresh() async {
    currentPage = 0;
    movieList.clear();
    loadMoreData();
    return null;
  }

异步加载数据,注意:在Flutter中刷新数据使用的是setState,不然无效,数据不会刷新;数据的获取需要使用[]取值,不能使用对象“ . ”的取值方法!

//加载列表数据
loadMoreData() async {
    this.currentPage  ;
    var start = (currentPage - 1) * pageSize;
    var url =
        "https://api.douban.com/v2/movie/$movieType?start=$start&count=$pageSize";
    Dio dio = new Dio();
    Response response = await dio.get(url);
    setState(() {
      movieList.addAll(response.data["subjects"]);
      totalSize = response.data["total"];
    });
  }

上拉加载更多

加载更多需要对ListView进行监听,所以需要进行监听器的设置,在State中进行监听器的初始化。

//初始化滚动监听器,加载更多使用
  ScrollController _controller = new ScrollController();

在构造器中设置监听

 //固定写法,初始化滚动监听器,加载更多使用
    _controller.addListener(() {
      var maxScroll = _controller.position.maxScrollExtent;
      var pixel = _controller.position.pixels;
      if (maxScroll == pixel && movieList.length < totalSize) {
        setState(() {
          loadMoreText = "正在加载中...";
          loadMoreTextStyle =
              new TextStyle(color: const Color(0xFF4483f6), fontSize: 14.0);
        });
        loadMoreData();
      } else {
        setState(() {
          loadMoreText = "没有更多数据";
          loadMoreTextStyle =
              new TextStyle(color: const Color(0xFF999999), fontSize: 14.0);
        });
      }
    });

在listView中添加监听controller方法

自此,Flutter如何实现下拉刷新和上拉加载更多完成…

整个列表页面代码参考如下:

import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:douban/pages/movie/movieDetail.dart';

class MovieList extends StatefulWidget {
  String movieType;
  //构造器传递数据(并且接收上个页面传递的数据)
  MovieList({Key key, this.movieType}) : super(key: key);
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new MovieListState(movieType: this.movieType);
  }
}

class MovieListState extends State<MovieList> {
  String movieType;
  String typeName;
  List movieList = new List();
  int currentPage = 0; //第一页
  int pageSize = 10; //页容量
  int totalSize = 0; //总条数
  String loadMoreText = "没有更多数据";
  TextStyle loadMoreTextStyle =
      new TextStyle(color: const Color(0xFF999999), fontSize: 14.0);
  TextStyle titleStyle =
      new TextStyle(color: const Color(0xFF757575), fontSize: 14.0);
  //初始化滚动监听器,加载更多使用
  ScrollController _controller = new ScrollController();

  /**
   * 构造器接收(MovieList)数据
   */
  MovieListState({Key key, this.movieType}) {
    //固定写法,初始化滚动监听器,加载更多使用
    _controller.addListener(() {
      var maxScroll = _controller.position.maxScrollExtent;
      var pixel = _controller.position.pixels;
      if (maxScroll == pixel && movieList.length < totalSize) {
        setState(() {
          loadMoreText = "正在加载中...";
          loadMoreTextStyle =
              new TextStyle(color: const Color(0xFF4483f6), fontSize: 14.0);
        });
        loadMoreData();
      } else {
        setState(() {
          loadMoreText = "没有更多数据";
          loadMoreTextStyle =
              new TextStyle(color: const Color(0xFF999999), fontSize: 14.0);
        });
      }
    });
  }

  //加载列表数据
  loadMoreData() async {
    this.currentPage  ;
    var start = (currentPage - 1) * pageSize;
    var url =
        "https://api.douban.com/v2/movie/$movieType?start=$start&count=$pageSize";
    Dio dio = new Dio();
    Response response = await dio.get(url);
    setState(() {
      movieList.addAll(response.data["subjects"]);
      totalSize = response.data["total"];
    });
  }

  @override
  void initState() {
    super.initState();
    //设置当前导航栏的标题
    switch (movieType) {
      case "in_theaters":
        typeName = "正在热映";
        break;
      case "coming_soon":
        typeName = "即将上映";
        break;
      case "top250":
        typeName = "Top250";
        break;
    }

    //加载第一页数据
    loadMoreData();
  }

  /**
   * 下拉刷新,必须异步async不然会报错
   */
  Future _pullToRefresh() async {
    currentPage = 0;
    movieList.clear();
    loadMoreData();
    return null;
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Scaffold(
      backgroundColor: Colors.white,
      appBar: new AppBar(
        leading: new IconButton(
          icon: const Icon(Icons.arrow_back),
          onPressed:null ,
        ),
        title: new Text(typeName != null ? typeName : "正在加载中...",
            style: new TextStyle(color: Colors.black)),
        backgroundColor: Colors.white,
      ),
      body: movieList.length == 0
          ? new Center(child: new CircularProgressIndicator())
          : new RefreshIndicator(
              color: const Color(0xFF4483f6),
              //下拉刷新
              child: ListView.builder(
                itemCount: movieList.length   1,
                itemBuilder: (context, index) {
                  if (index == movieList.length) {
                    return _buildProgressMoreIndicator();
                  } else {
                    return renderRow(index, context);
                  }
                },
                controller: _controller, //指明控制器加载更多使用
              ),
              onRefresh: _pullToRefresh,
            ),
    );
  }

  /**
   * 加载更多进度条
   */
  Widget _buildProgressMoreIndicator() {
    return new Padding(
      padding: const EdgeInsets.all(15.0),
      child: new Center(
        child: new Text(loadMoreText, style: loadMoreTextStyle),
      ),
    );
  }

  /**
   * 列表的ltem
   */
  renderRow(index, context) {
    var movie = movieList[index];
    var id = movie["id"];
    var title = movie["title"];
    var type = movie["genres"].join("、");
    var year = movie["year"];
    var score = movie["rating"]["average"];
    return new Container(
        height: 200,
        color: Colors.white,
        child: new InkWell(
          onTap: () {
            Navigator.of(context).push(new MaterialPageRoute(
                builder: (ctx) => new MovieDetail(movieId: id)));
          },
          child: new Column(
            children: <Widget>[
              new Container(
                height: 199,
                // color: Colors.blue,
                child: new Row(
                  children: <Widget>[
                    new Container(
                      width: 120.0,
                      height: 180.0,
                      margin: const EdgeInsets.all(10.0),
                      child: Image.network(movie["images"]["small"]),
                    ),
                    Expanded(
                      child: new Container(
                        height: 180.0,
                        margin: const EdgeInsets.all(12.0),
                        child: new Column(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            new Text(
                              "电影名称:$title",
                              style: titleStyle,
                              overflow: TextOverflow.ellipsis,
                            ),
                            new Text(
                              "电影类型:$type",
                              style: titleStyle,
                              overflow: TextOverflow.ellipsis,
                            ),
                            new Text(
                              "上映年份:$year",
                              style: titleStyle,
                              overflow: TextOverflow.ellipsis,
                            ),
                            new Text(
                              "豆瓣评分:$score",
                              style: titleStyle,
                              overflow: TextOverflow.ellipsis,
                            )
                          ],
                        ),
                      ),
                    ),
                  ],
                ),
              ),
              //分割线
              new Divider(height: 1)
            ],
          ),
        ));
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持Devmax。

Flutter实现下拉刷新和上拉加载更多的更多相关文章

  1. Flutter中文教程-Cookbook

    Flutter中文网的Cookbook中包含了在编写Flutter应用程序时常见问题及示例。设计基础使用主题共享颜色和字体样式Images显示来自网上的图片用占位符淡入图片使用缓存图Lists创建一个基本list创建一个水平list使用长列表创建不同类型子项的List创建一个gridList处理手势处理点击添加Material触摸水波效果实现滑动关闭导航导航到新页面并返回给新页面传值从新页面返回数据给上一个页面网络从网上获取数据进行认证请求使用WebSockets

  2. android-studio – 未配置Dart SDK

    Initializinggradle…

  3. 安卓 – 从一个扑动的应用程序拨打电话

    或者有更好的选择从我的应用程序拨打电话?

  4. android – 如何在Flutter中添加Webview?

    我知道可以将WebView添加为整页,但找不到任何示例代码.我假设你可以使用PageView作为它的基础,但不知道如何调用本机androidWebView并将其添加到PageView.谁能指出我正确的方向?

  5. android – 如何将消息从Flutter传递给Native?

    如果需要与特定的API/硬件组件进行交互,您如何将Flutter的信息传递回Android/Native代码?是否有任何事件频道可以通过其他方式发送信息或类似于回调?

  6. android – 如何在Flutter App中处理onPause / onResume?

    我是否过于复杂的事情?即使我的用例似乎不需要它,我仍然想知道:如何自己处理onPause/onResume事件?

  7. android – 如何使用Flutter构建Augment Reality应用程序?

    我对Android开发有一些基础知识.最近听说过Flutter并且非常有兴趣研究它.我想知道是否有可能使用颤振构建增强现实应用程序以及要实现此目的的方法?请帮忙.解决方法截至目前,颤振不支持3D.Flutter现在专注于2D,团队长期计划为颤振提供优化的3Dapi.你读了常见问题here.

  8. Flutter 网络请求框架封装详解

    这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. vue自定义加载指令v-loading占位图指令v-showimg

    这篇文章主要为大家介绍了vue自定义加载指令和v-loading占位图指令v-showimg的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. Flutter StreamBuilder实现局部刷新实例详解

    这篇文章主要为大家介绍了Flutter StreamBuilder实现局部刷新实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

随机推荐

  1. Flutter 网络请求框架封装详解

    这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Android单选按钮RadioButton的使用详解

    今天小编就为大家分享一篇关于Android单选按钮RadioButton的使用详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

  3. 解决android studio 打包发现generate signed apk 消失不见问题

    这篇文章主要介绍了解决android studio 打包发现generate signed apk 消失不见问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  4. Android 实现自定义圆形listview功能的实例代码

    这篇文章主要介绍了Android 实现自定义圆形listview功能的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. 详解Android studio 动态fragment的用法

    这篇文章主要介绍了Android studio 动态fragment的用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. Android用RecyclerView实现图标拖拽排序以及增删管理

    这篇文章主要介绍了Android用RecyclerView实现图标拖拽排序以及增删管理的方法,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下

  7. Android notifyDataSetChanged() 动态更新ListView案例详解

    这篇文章主要介绍了Android notifyDataSetChanged() 动态更新ListView案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

  8. Android自定义View实现弹幕效果

    这篇文章主要为大家详细介绍了Android自定义View实现弹幕效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. Android自定义View实现跟随手指移动

    这篇文章主要为大家详细介绍了Android自定义View实现跟随手指移动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Android实现多点触摸操作

    这篇文章主要介绍了Android实现多点触摸操作,实现图片的放大、缩小和旋转等处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部