热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

FlutterListView如何实现上拉加载更多下拉刷新功能

这篇文章给大家分享的是有关FlutterListView如何实现上拉加载更多下拉刷新功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小

这篇文章给大家分享的是有关Flutter ListView如何实现上拉加载更多下拉刷新功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

先上图

Flutter ListView如何实现上拉加载更多下拉刷新功能

下拉刷新

跟原生开发一样,下拉刷新在flutter里提供的有组件实现 RefreshIndicator

一直不明白为啥组件中都提供下拉刷新,但就是没有上拉加载!!

我这请求接口数据用的是 http 库,是个第三方的是需要安装的 https://pub.dev/packages/http

用法如下

class MyHomePage extends StatefulWidget {
 MyHomePage({Key key}) : super(key: key);
 @override
 MyHomeWidget2 createState() => MyHomeWidget2();
}
class MyHomeWidget2 extends State {
 int page = 1;
 List data = new List();
 var baseUrl = "https://cnodejs.org/api/v1";
 @override
 void initState() {
 super.initState();
 this._onRefresh();
 }
 _fetchData() async {
 var response = await http.get(
  '${this.baseUrl}/topics?mdrender=false&limit=10&page=${this.page}');
 var json = await convert.jsonDecode(response.body);
 return json['data'];
 }
 Future _onRefresh() {
 data.clear();
 this.page = 1;
 return _fetchData().then((data) {
  setState(() => this.data.addAll(data));
 });
 }
 @override
 Widget build(BuildContext context) {
 return Scaffold(
  body: RefreshIndicator( // 在ListView外包一层 RefreshIndicator 组件
  onRefresh: _onRefresh, // 添加onRefresh方法
  child: ListView.separated(
   itemCount: this.data.length,
   itemBuilder: (context, index) {
   var _data = this.data[index];
   return ListTile(
    leading: Image.network(_data["author"]["avatar_url"]),
    title: Text(_data["title"]),
    subtitle: Text(_data["author"]["loginname"] +
     " created at " +
     new DateTime.now().toString()), // 为了看每次数据变动,这里直接取当前时间
    trailing: Icon(Icons.chevron_right));
   },
   separatorBuilder: (context, index) {
   return Divider();
   },
  )
 ));
 }
}

链接文原: https://tomoya92.github.io/2019/07/17/flutter-refresh-loadmore/

上拉加载

上拉加载原理还是一样的,给ListView加一个 ScrollController 组件,然后通过事件监听滚动条的高度来显示和隐藏加载更多的组件

先将加载更多的组件写好

Widget _loadMoreWidget() {
 return new Padding(
 padding: const EdgeInsets.all(15.0), // 外边距
 child: new Center(
  child: new CircularProgressIndicator()
 ),
 );
}

初始化一个 ScrollController 组件,将其设置给 ListView 组件的 controller 属性上

ScrollController _scrollController = new ScrollController();

child: ListView.separated(
 controller: _scrollController,
 //...
)

然后通过重写 dispost() 方法来处理加载更多组件的释放

@override
void dispose() {
 _scrollController.dispose();
 super.dispose();
}

最后通过数据源来控制界面渲染哪个组件,当数据源循环渲染的 index 跟数据源一样长时(其实少1,下标从0开始的)就渲染加载更多组件,让其显示出来,同时调用加载更多方法,获取数据,再通过state实现组件ui的更新

完整代码如下

class MyHomePage extends StatefulWidget {
 MyHomePage({Key key}) : super(key: key);
 @override
 MyHomeWidget2 createState() => MyHomeWidget2();
}
class MyHomeWidget2 extends State {
 int page = 1;
 bool isLoadmore = false;
 List data = new List();
 var baseUrl = "https://cnodejs.org/api/v1";
 ScrollController _scrollController = new ScrollController();
 @override
 void initState() {
 super.initState();
 this._onRefresh();
 _scrollController.addListener(() {
  if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
  _onLoadmore();
  }
 });
 }
 _fetchData() async {
 var response = await http.get(
  '${this.baseUrl}/topics?mdrender=false&limit=10&page=${this.page}');
 var json = await convert.jsonDecode(response.body);
 return json['data'];
 }
 Future _onRefresh() {
 data.clear();
 this.page = 1;
 return _fetchData().then((data) {
  setState(() => this.data.addAll(data));
 });
 }
 Future _onLoadmore() {
 this.page++;
 return _fetchData().then((data) {
  setState((){
  this.data.addAll(data);
  isLoadmore = false;
  });
 });
 }
 @override
 void dispose() {
 _scrollController.dispose();
 super.dispose();
 }
 Widget _loadMoreWidget() {
 return new Padding(
  padding: const EdgeInsets.all(15.0),
  child: new Center(
  child: new CircularProgressIndicator()
  ),
 );
 }
 @override
 Widget build(BuildContext context) {
 return Scaffold(
  body: RefreshIndicator(
  onRefresh: _onRefresh,
  child: ListView.separated(
   controller: _scrollController,
   itemCount: this.data.length,
   itemBuilder: (context, index) {
   if (index == data.length - 1) {
    return _loadMoreWidget();
   } else {
    var _data = this.data[index];
    return ListTile(
     leading: Image.network(_data["author"]["avatar_url"]),
     title: Text(_data["title"]),
     subtitle: Text(_data["author"]["loginname"] +
      " created at " +
      new DateTime.now().toString()),
     trailing: Icon(Icons.chevron_right));
   }
   },
   separatorBuilder: (context, index) {
   return Divider();
   },
  )
 ));
 }
}

感谢各位的阅读!关于“Flutter ListView如何实现上拉加载更多下拉刷新功能”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!


推荐阅读
author-avatar
海and云
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有