参考
Flutter下拉刷新和上拉加载更多
下拉刷新
上拉加载更多
下拉刷新直接用flutter自带的控件RefreshIndicator组件即可,上拉加载可以通过ListView 中的ScrollController 属性,根据 ListView 的位置来判断是否滑动到了底部来做加载更多的处理
下面用们用到的json数据接口为:https://jsonplaceholder.typicode.com/posts/1/comments
下拉刷新
就是在我们上一节讲到的解析的列表外面嵌套一个RefreshIndicator,然后通过onRefresh进行监听
@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("请求数据 Dio Demo"),),body: this._list.length > 0? RefreshIndicator(onRefresh: _onRefresh,child: ListView.builder(itemCount: this._list.length,itemBuilder: (context, index) {return ListTile(title: Text(_list[index]["email"], maxLines: 1),));})): Text("加载中..."));}Future<void> _onRefresh() async {print('执行刷新');_getData();await Future.delayed(Duration(seconds: 3), () {print('refresh');});}_getData() async {var apiUrl = "https://jsonplaceholder.typicode.com/posts/${_page}/comments";Response result = await Dio().get(apiUrl);setState(() {_list.addAll(result.data);_page++;});print("获取数据操作");}
上拉加载更多
通过ListView 中的ScrollController 属性,根据 ListView 的位置来判断是否滑动到了底部来做加载更多的处理
_scrollController.position.pixels 滚动的距离
_scrollController.position.maxScrollExtent 总距离
自定义下部加载的控件
Widget _getMoreWidget() {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,)],),),);}
ScrollController _scrollController = ScrollController(); //listview 的控制器List _list = [];int _page = 1;bool isLoading = false;@overridevoid initState() {super.initState();_getData();//监听划到最底部就进行if内的操作_scrollController.addListener(() {if (_scrollController.position.pixels >_scrollController.position.maxScrollExtent - 20) {print('滑动到了最底部');_getData();}});}
ListView.builder(itemCount: _list.length,controller: _scrollController,itemBuilder: (context, index) {if (index == _list.length - 1) {return Column(children: <Widget>[ListTile(title: Text(_list[index]["email"], maxLines: 1),),Divider(),//如果条目达到最底部,则还要展示一个加载圈_getMoreWidget()],);} else {//没有到达底部直接加载条目return Column(children: <Widget>[ListTile(title: Text(_list[index]["email"], maxLines: 1),),Divider()],);}}))
代码:
// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables, avoid_print, prefer_is_empty, slash_for_doc_comments, unnecessary_brace_in_string_interps, prefer_const_constructors_in_immutables, prefer_final_fieldsimport 'package:flutter/material.dart';
import 'package:dio/dio.dart';class LoadMorePage extends StatefulWidget {LoadMorePage({Key? key}) : super(key: key);@override_LoadMorePageState createState() => _LoadMorePageState();
}class _LoadMorePageState extends State<LoadMorePage> {ScrollController _scrollController = ScrollController(); //listview 的控制器List _list = [];int _page = 1;bool isLoading = false;var json; //是否正在加载数据@overridevoid initState() {super.initState();//之所以写三遍是因为我发现接口中每一页数据较少,第一次加载一页达不到底部,监听不到滑动_getData();_getData();_getData();print("到达了最底部。。。");//下面这个方法每次都底部都会执行,上面的代码只会执行一次_scrollController.addListener(() {if (_scrollController.position.pixels >_scrollController.position.maxScrollExtent - 20) {print('滑动到了最底部');_getData();}});}_getData() async {var apiUrl ="https://jsonplaceholder.typicode.com/posts/${_page}/comments";Response result = await Dio().get(apiUrl);
// print(json.decode(result.data)["result"]);setState(() {_list.addAll(result.data);_page++;});}/**
* 加载更多时显示的组件,给用户提示
*/Widget _getMoreWidget() {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,)],),),);}Future<void> _onRefresh() async {print('执行刷新');
// this._getData();await Future.delayed(Duration(seconds: 3), () {print('refresh');});}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("请求数据"),),body: _list.length > 0? RefreshIndicator(onRefresh: _onRefresh,child: ListView.builder(itemCount: _list.length,controller: _scrollController,itemBuilder: (context, index) {if (index == _list.length - 1) {return Column(children: <Widget>[ListTile(title:Text(_list[index]["email"], maxLines: 1),),Divider(),//如果条目达到最底部,则还要展示一个加载圈_getMoreWidget()],);} else {//没有到达底部直接加载条目return Column(children: <Widget>[ListTile(title:Text(_list[index]["email"], maxLines: 1),),Divider()],);}})): _getMoreWidget());}
}



















