经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Flutter » 查看文章
Flutter ListView 上拉加载更多下拉刷新功能实现方法
来源:jb51  时间:2019/7/22 11:23:37  对本文有异议

先上图

下拉刷新

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

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

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

用法如下

  1. class MyHomePage extends StatefulWidget {
  2. MyHomePage({Key key}) : super(key: key);
  3. @override
  4. MyHomeWidget2 createState() => MyHomeWidget2();
  5. }
  6. class MyHomeWidget2 extends State<MyHomePage> {
  7. int page = 1;
  8. List data = new List();
  9. var baseUrl = "https://cnodejs.org/api/v1";
  10. @override
  11. void initState() {
  12. super.initState();
  13. this._onRefresh();
  14. }
  15. _fetchData() async {
  16. var response = await http.get(
  17. '${this.baseUrl}/topics?mdrender=false&limit=10&page=${this.page}');
  18. var json = await convert.jsonDecode(response.body);
  19. return json['data'];
  20. }
  21. Future<dynamic> _onRefresh() {
  22. data.clear();
  23. this.page = 1;
  24. return _fetchData().then((data) {
  25. setState(() => this.data.addAll(data));
  26. });
  27. }
  28. @override
  29. Widget build(BuildContext context) {
  30. return Scaffold(
  31. body: RefreshIndicator( // 在ListView外包一层 RefreshIndicator 组件
  32. onRefresh: _onRefresh, // 添加onRefresh方法
  33. child: ListView.separated(
  34. itemCount: this.data.length,
  35. itemBuilder: (context, index) {
  36. var _data = this.data[index];
  37. return ListTile(
  38. leading: Image.network(_data["author"]["avatar_url"]),
  39. title: Text(_data["title"]),
  40. subtitle: Text(_data["author"]["loginname"] +
  41. " created at " +
  42. new DateTime.now().toString()), // 为了看每次数据变动,这里直接取当前时间
  43. trailing: Icon(Icons.chevron_right));
  44. },
  45. separatorBuilder: (context, index) {
  46. return Divider();
  47. },
  48. )
  49. ));
  50. }
  51. }

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

上拉加载

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

先将加载更多的组件写好

  1. Widget _loadMoreWidget() {
  2. return new Padding(
  3. padding: const EdgeInsets.all(15.0), // 外边距
  4. child: new Center(
  5. child: new CircularProgressIndicator()
  6. ),
  7. );
  8. }

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

  1. ScrollController _scrollController = new ScrollController();
  2.  
  3. child: ListView.separated(
  4. controller: _scrollController,
  5. //...
  6. )

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

  1. @override
  2. void dispose() {
  3. _scrollController.dispose();
  4. super.dispose();
  5. }

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

完整代码如下

  1. class MyHomePage extends StatefulWidget {
  2. MyHomePage({Key key}) : super(key: key);
  3. @override
  4. MyHomeWidget2 createState() => MyHomeWidget2();
  5. }
  6. class MyHomeWidget2 extends State<MyHomePage> {
  7. int page = 1;
  8. bool isLoadmore = false;
  9. List data = new List();
  10. var baseUrl = "https://cnodejs.org/api/v1";
  11. ScrollController _scrollController = new ScrollController();
  12. @override
  13. void initState() {
  14. super.initState();
  15. this._onRefresh();
  16. _scrollController.addListener(() {
  17. if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
  18. _onLoadmore();
  19. }
  20. });
  21. }
  22. _fetchData() async {
  23. var response = await http.get(
  24. '${this.baseUrl}/topics?mdrender=false&limit=10&page=${this.page}');
  25. var json = await convert.jsonDecode(response.body);
  26. return json['data'];
  27. }
  28. Future<dynamic> _onRefresh() {
  29. data.clear();
  30. this.page = 1;
  31. return _fetchData().then((data) {
  32. setState(() => this.data.addAll(data));
  33. });
  34. }
  35. Future<dynamic> _onLoadmore() {
  36. this.page++;
  37. return _fetchData().then((data) {
  38. setState((){
  39. this.data.addAll(data);
  40. isLoadmore = false;
  41. });
  42. });
  43. }
  44. @override
  45. void dispose() {
  46. _scrollController.dispose();
  47. super.dispose();
  48. }
  49. Widget _loadMoreWidget() {
  50. return new Padding(
  51. padding: const EdgeInsets.all(15.0),
  52. child: new Center(
  53. child: new CircularProgressIndicator()
  54. ),
  55. );
  56. }
  57. @override
  58. Widget build(BuildContext context) {
  59. return Scaffold(
  60. body: RefreshIndicator(
  61. onRefresh: _onRefresh,
  62. child: ListView.separated(
  63. controller: _scrollController,
  64. itemCount: this.data.length,
  65. itemBuilder: (context, index) {
  66. if (index == data.length - 1) {
  67. return _loadMoreWidget();
  68. } else {
  69. var _data = this.data[index];
  70. return ListTile(
  71. leading: Image.network(_data["author"]["avatar_url"]),
  72. title: Text(_data["title"]),
  73. subtitle: Text(_data["author"]["loginname"] +
  74. " created at " +
  75. new DateTime.now().toString()),
  76. trailing: Icon(Icons.chevron_right));
  77. }
  78. },
  79. separatorBuilder: (context, index) {
  80. return Divider();
  81. },
  82. )
  83. ));
  84. }
  85. }

总结

以上所述是小编给大家介绍的Flutter ListView 上拉加载更多下拉刷新功能实现方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对w3xue网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号