IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Flutter 给列表增加下拉刷新和上滑加载更多功能 -> 正文阅读

[JavaScript知识库]Flutter 给列表增加下拉刷新和上滑加载更多功能

在实际的 App 中,下拉刷新和上滑加载更多是非常常见的交互形式。在 Flutter 中,有 flutter_easyrefresh开源插件用于实现下拉刷新和上滑加载更多。本篇介绍了有状态组件和 flutter_easyrefresh 的基本应用,同时使用模拟的方式完成了异步数据加载。

有状态组件

当 Flutter 的页面需要动态更新数据的时候,就会涉及到 UI 组件需要根据数据变化更新,此时也就意味着组件有了“状态”。这就类似 React 的类组件和函数组件(只是后续 React 使用了勾子函数实现了函数组件也可以有状态)。在 Flutter 中,组件也分为无状态组件(StatelessWidget)和有状态组件(StatefulWidget),一般尽量使用无状态组件。但是如果组件本身需要维护自身状态的时候,就需要使用有状态组件了。有状态组件的定义形式如下:

//有状态组件声明
class DynamicPage extends StatefulWidget {
  DynamicPage({Key key}) : super(key: key);

  //创建组件状态
  @override
  _DynamicPageState createState() => _DynamicPageState();
}

//组件状态
class _DynamicPageState extends State<DynamicPage> {
  @override
  Widget build(BuildContext context) {
    //UI 构建
  }
}

有状态组件实际的业务逻辑均由对应的状态实现,包括数据定义和 UI 构建。其核心在于有一个 setState 方法用于通知界面刷新(这点也和 React 类似),一旦主动调用了 setState 方法,界面就会进行刷新。当然,其中还有一些别的与状态相关的方法,如状态初始化方法 initialState。

异步 async/await

在网络请求中,不可避免需要用到异步请求,这个时候就需要使用到 async 和 await。标记为 async 的函数返回结果是一个 Future 包裹的对象,调用方可以使用 await 从中获取实际返回的数据。async/await 这个配对就完成了一个异步调用过程。在结果没有返回的时候,主线程会执行其他任务。在这里我们将列表数据获取的方法改为 async 方式,以模拟网络请求,如下所示:

static Future<List<Map<String, Object>>> list(int page, int size) async {
    return List<Map<String, Object>>.generate(size, (index) {
      return {
        'title': '标题${index + (page - 1) * size + 1}:这是一个列表标题,最多两行,多处部分将会被截取',
        'imageUrl':
            'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3331308357,177638268&fm=26&gp=0.jpg',
        'viewCount': 180,
      };
    });
  }

调用的时候,使用 await即可获取实际结果数据,如下所示:

// _currentPage 为当前页码,PAGE_SIZE为分页大小
List<Map<String, Object>> _newItems =
        await DynamicMockData.list(_currentPage, PAGE_SIZE);

引入 flutter_easyrefresh

flutter 需要引入第三方插件时,需要在 pubspec.yaml 文件下的dependencies节点下增加依赖,撰写本文时flutter_easyrefresh的最新版为2.2.1,因此指定版本如下:

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  flutter_easyrefresh: ^2.2.1

添加完依赖后,需要在项目目录执行 flutter pub get 命令更新依赖(VSCode 在检测到 pubspec.yaml变化时会自动拉取)。

使用 flutter_easyrefresh

对上一篇中的列表(Flutter 入门与实战(五):来一个图文并茂的列表)进行改造,分为如下三个步骤:

  • 将页面修改为有状态组件,方便支持管理数据和根据数据更新界面
  • 使用 EasyRefresh 包裹列表组件,并指定 onRefresh 和 onLoad 回调方法,以响应下拉刷新和上滑加载更多的动作。
  • 根据当前分页获取数据,并更新到列表数据中,再调用 setState 更新状态数据刷新界面。

整个新的 dynamic_page 的代码如下所示:

import 'package:flutter/material.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import 'dynamic_item.dart';
import 'dynamic_mock_data.dart';

class DynamicPage extends StatefulWidget {
  DynamicPage({Key key}) : super(key: key);

  @override
  _DynamicPageState createState() => _DynamicPageState();
}

class _DynamicPageState extends State<DynamicPage> {
  List<Map<String, Object>> _listItems = [];
  int _currentPage = 1;
  static const int PAGE_SIZE = 20;

  void _refresh() async {
    _currentPage = 1;
    _requestNewItems();
  }

  void _load() async {
    _currentPage += 1;
    _requestNewItems();
  }

  void _requestNewItems() async {
    List<Map<String, Object>> _newItems =
        await DynamicMockData.list(_currentPage, PAGE_SIZE);
    this.setState(() {
      if (_currentPage > 1) {
        _listItems += _newItems;
      } else {
        _listItems = _newItems;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: EasyRefresh(
        onRefresh: () async {
          _refresh();
        },
        onLoad: () async {
          _load();
        },
        child: ListView.builder(
            itemCount: _listItems.length,
            itemBuilder: (context, index) {
              return DynamicItem(
                _listItems[index]['title'],
                _listItems[index]['imageUrl'],
                _listItems[index]['viewCount'],
              );
            }),
      ),
    );
  }
}

运行结果

运行结果如下图所示,由于上拉加载过快没法直接截图看到。需要注意的是,首次加载的时候,EasyRefresh 并不会自动加载,这个时候需要使用 EasyRefreshController 来控制,有兴趣的同学可以参考 flutter_easyfresh 的文档实现。
refresh.jpg

结语

flutter_easyrefresh 可以实现丰富的加载效果,包括自定义加载组件,乃至使用有趣的动画等等,基本上可以满足各类下拉刷新或上滑加载更多的需要。建议可以参考文档多尝试其他效果,有兴趣的也可以阅读源码看看具体的实现方式。

关注岛上码农

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-20 18:18:19  更:2021-11-20 18:18:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:21:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码