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 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Flutter 上滑加载以及下拉刷新 -> 正文阅读

[移动开发]Flutter 上滑加载以及下拉刷新

实现下拉刷新

  • flutter中,已经给出了实现,咱们只需要给出回调即可。
  • 很多解释都在注释中,请不要忽略。
  • 如果你想要直接看到全部代码,请拉到最后。
import 'dart:async';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_demo/base/view.dart';
import 'package:flutter_demo/common/my_flutter_toast/MyToast.dart';
import 'package:flutter_demo/common/my_flutter_toast/ToastType.dart';
import 'package:flutter_demo/view/news/NewsItem.dart';
import 'Model.dart';

class NewsPage extends StatefulWidget {
  @override
  _NewsPageState createState() => _NewsPageState();
}

class _NewsPageState extends State<NewsPage> {
  List _goodsList = [];
  int _currentPage = 1;
  int _pageSize = 15;
  //数据是否全部加载完毕
  bool _isOver = false;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    this._initData();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
    // 封装的工具方法,如果使用请修改为正常写法
      appBar: getAppBar('News Center'),
      body: RefreshIndicator(
          onRefresh: () async {
          // 这里写下拉刷新后执行的代码
            print(1);
          },
          child: ListView.builder(
            itemBuilder: _builder,
            itemCount: this._goodsList.length,
          )),
    );
  }

  Widget _builder(BuildContext context, int index) {
    return NewsItem(Goods(
      this._goodsList[index]['title'],
      this._goodsList[index]['id'],
      this._goodsList[index]['price'],
      this._goodsList[index]['category'],
    ));
  }

  /*
    获取数据
   */
  _loadData() async {
  //请自行写一个接口,或者使用定时器来模拟
    final Response res = await Dio().get(
        'http://localhost:3000/flutter?page=${this._currentPage}&pageSize=${this._pageSize}');
	//请求成功或再做处理
    if (res.statusCode == 200 && res.data['success'] == true) {
    //不要忘记赋值操作要在这个函数中
      setState(() {
      //如果该次请求的数据量小于每页的最大数据量,则判断为全部加载完毕
        if (res.data['result'].length < this._pageSize) {
          this._isOver = true;
        }
        //当前的页数要加1
        this._currentPage++;
        this._goodsList.addAll(res.data['result']);
      });
    }
  }

  //首次加载有loading提示
  _initData() async {
    Timer(Duration.zero, () {
      MyToast.showToast(
          context: context, type: ToastType.loading, message: '正在加载');
    });

    await this._loadData();
    MyToast.hideToast(context);
  }
}

在这里插入图片描述
RefreshIndicator该组件即为flutter实现的下拉刷新组件,它有一个必需参数为onRefresh,接收一个Future类型的函数。你可以在下拉后进行一些异步操作。

实现上滑加载

在完成了下拉刷新的基础上,我们需要借用ScrollController来判断页面滚动条是否拉到底部,从而请求数据。

  • 在类中声明变量ScrollController _scrollController = ScrollController();
  • ListView中添加一条参数controller: this._scrollController,
  • initState()中注册监听
this._scrollController.addListener(() async {
      //滑到底部时触发
      if (this._scrollController.position.pixels >=
          this._scrollController.position.maxScrollExtent) {
        if (!this._isOver) {
        	this._loadData();
        }
      }
    });
  • 补充上一条,如果你足够细心,会发现此种写法在你上滑到底部时,触发多次,这就需要节流操作。如下所示,这样的作用为在100ms内,若多次触发了"上滑到底部"这个事件,网络请求也只会发出一次。注意在类中声明变量Timer? _timer;
this._scrollController.addListener(() async {
      //滑到底部时触发
      if (this._scrollController.position.pixels >=
          this._scrollController.position.maxScrollExtent) {
        if (!this._isOver) {
          //节流
          if (this._timer != null) this._timer!.cancel();
          this._timer = Timer(Duration(milliseconds: 100), () {
            this._loadData();
          });
        }
      }
    });
  • 最后,在组件销毁时,要将_scrollController销毁。
  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    this._scrollController.dispose();
  }

全部代码

主要实现页

import 'dart:async';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_demo/base/view.dart';
import 'package:flutter_demo/common/my_flutter_toast/MyToast.dart';
import 'package:flutter_demo/common/my_flutter_toast/ToastType.dart';
import 'package:flutter_demo/view/news/NewsItem.dart';
import 'Model.dart';

class NewsPage extends StatefulWidget {
  @override
  _NewsPageState createState() => _NewsPageState();
}

class _NewsPageState extends State<NewsPage> {
  ScrollController _scrollController = ScrollController();
  List _goodsList = [];
  int _currentPage = 1;
  int _pageSize = 15;
  bool _isOver = false;
  //节流阀
  Timer? _timer;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    this._initData();

    this._scrollController.addListener(() async {
      //滑到底部时触发
      if (this._scrollController.position.pixels >=
          this._scrollController.position.maxScrollExtent) {
        if (!this._isOver) {
          //节流
          if (this._timer != null) this._timer!.cancel();
          this._timer = Timer(Duration(milliseconds: 100), () {
            this._loadData();
          });
        }
      }
    });
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    this._scrollController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: getAppBar('News Center'),
      body: RefreshIndicator(
          onRefresh: () async {
            print(1);
          },
          child: ListView.builder(
            itemBuilder: _builder,
            itemCount: this._goodsList.length,
            controller: this._scrollController,
          )),
    );
  }

  Widget _builder(BuildContext context, int index) {
    return NewsItem(Goods(
      this._goodsList[index]['title'],
      this._goodsList[index]['id'],
      this._goodsList[index]['price'],
      this._goodsList[index]['category'],
    ));
  }

  /*
    获取数据
   */
  _loadData() async {
    final Response res = await Dio().get(
        'http://localhost:3000/flutter?page=${this._currentPage}&pageSize=${this._pageSize}');

    if (res.statusCode == 200 && res.data['success'] == true) {
      setState(() {
        if (res.data['result'].length < this._pageSize) {
          this._isOver = true;
        }
        this._currentPage++;
        this._goodsList.addAll(res.data['result']);
      });
    }
  }

  //首次加载有loading提示
  _initData() async {
    Timer(Duration.zero, () {
      MyToast.showToast(
          context: context, type: ToastType.loading, message: '正在加载');
    });

    await this._loadData();
    MyToast.hideToast(context);
  }
}

子组件

import 'package:flutter/material.dart';
import 'Model.dart';

class NewsItem extends StatelessWidget {
  final Goods _item;
  NewsItem(this._item);

  @override
  Widget build(BuildContext context) {
    return ListTile(
        title: Text(this._item.title),
        subtitle: Text(
            '分类ID:${this._item.category}    价格:¥${this._item.price}   商品ID:${this._item.id}'));
  }
}

数据模型

class Goods {
  String title;
  int id;
  double price;
  int category;

  Goods(this.title, this.id, this.price, this.category);
}

求赞!

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-09-08 10:51:10  更:2021-09-08 10:53:40 
 
开发: 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/23 16:45:34-

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