Flutter ListView懒加载(滑动不加载,停止滑动加载)

简介: 前言:为了更好的减小网络的带宽,使得列表更加流畅,我们需要了解懒加载,也称延迟加载。关于上一章的登录界面,各位属实难为我了,我也在求ui小姐姐,各位点点赞给我点动力吧~

前言:为了更好的减小网络的带宽,使得列表更加流畅,我们需要了解懒加载,也称延迟加载。 面试真题:flutter如何实现懒加载?

关于上一章的登录界面,各位属实难为我了,我也在求ui小姐姐,各位点点赞给我点动力吧~

5e3c9f11dc5c8d53c46907cf16e2b5e.jpg
ca.png

image.png

懒加载也叫延迟加载,指的是在长网页中延迟加载图像,是一种很好优化网页性能的方式。用户滚动到它们之前,可视区域外的图像不会加载。这与图像预加载相反,在长网页上使用延迟加载将使网页加载更快。在某些情况下,它还可以帮助减少服务器负载。常适用图片很多,页面很长的电商网站场景中。

对ListView优化就那么几点:(后面都会写出来):

1.Flutter ListView加载图片优化(懒加载)

2.Flutter ListView加载时使用图片使用缩略图,对图片进行缓存

3.Flutter 减少build()的耗时

本章,我们会实现wechat朋友圈的优化功能,即当页面在滑动时不加载图片,在界面停止滑动时加载图片。
效果图:

tt0.top-288153.gif

1.了解widget通知监听:NotificationListener

NotificationListener属性:

  • child:widget
  • onNotification:NotificationListenerCallback<Notification>

    返回值true表示消费掉当前通知不再向上一级NotificationListener传递通知,false则会再向上一级NotificationListener传递通知;这里需要注意的是通知是由下而上去传递的,所以才会称作冒泡通知!

2.需要一个bool来控制是否加载

///加载图片的标识
bool isLoadingImage = true;

3.编写传递通知的方法,使其作用于NotificationListener

bool notificationFunction(Notification notification) {
  ///通知类型
  switch (notification.runtimeType) {
    case ScrollStartNotification:
      print("开始滚动");
​
      ///在这里更新标识 刷新页面 不加载图片
      isLoadingImage = false;
      break;
    case ScrollUpdateNotification:
      print("正在滚动");
      break;
    case ScrollEndNotification:
      print("滚动停止");
​
      ///在这里更新标识 刷新页面 加载图片
      setState(() {
        isLoadingImage = true;
      });
      break;
    case OverscrollNotification:
      print("滚动到边界");
      break;
  }
  return true;
}

4.根据bool值加载不同的组件

ListView buildListView() {
  return ListView.separated(
    itemCount: 1000, //子条目个数
    ///构建每个条目
    itemBuilder: (BuildContext context, int index) {
      if (isLoadingImage) {
        ///这时将子条目单独封装在了一个StatefulWidget中
        return Image.network(
          netImageUrl,
          width: 100,
          height: 100,
          fit: BoxFit.fitHeight,
        );
      } else {
        return Container(
          height: 100,
          width: 100,
          child: Text("加载中..."),
        ); //占位
      }
    },
​
    ///构建每个子Item之间的间隔Widget
    separatorBuilder: (BuildContext context, int index) {
      return new Divider();
    },
  );
}

完整代码:

class ScrollHomePageState extends State {
  ///加载图片的标识
  bool isLoadingImage = true;
​
  ///网络图片地址
  String netImageUrl =
      "https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0a4ce25d48b8405cbf5444b6195928d4~tplv-k3u1fbpfcp-no-mark:0:0:0:0.awebp";
​
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(
        title: Text("详情"),
      ),
      ///列表
      body: NotificationListener(
        ///子Widget中的滚动组件滑动时就会分发滚动通知
        child: buildListView(),
        ///每当有滑动通知时就会回调此方法
        onNotification: notificationFunction,
      ),
    );
  }
​
  bool notificationFunction(Notification notification) {
    ///通知类型
    switch (notification.runtimeType) {
      case ScrollStartNotification:
        print("开始滚动");
​
        ///在这里更新标识 刷新页面 不加载图片
        isLoadingImage = false;
        break;
      case ScrollUpdateNotification:
        print("正在滚动");
        break;
      case ScrollEndNotification:
        print("滚动停止");
​
        ///在这里更新标识 刷新页面 加载图片
        setState(() {
          isLoadingImage = true;
        });
        break;
      case OverscrollNotification:
        print("滚动到边界");
        break;
    }
    return true;
  }
​
  ListView buildListView() {
    return ListView.separated(
      itemCount: 1000, //子条目个数
      ///构建每个条目
      itemBuilder: (BuildContext context, int index) {
        if (isLoadingImage) {
          ///这时将子条目单独封装在了一个StatefulWidget中
          return Image.network(
            netImageUrl,
            width: 100,
            height: 100,
            fit: BoxFit.fitHeight,
          );
        } else {
          return Container(
            height: 100,
            width: 100,
            child: Text("加载中..."),
          ); //占位
        }
      },
​
      ///构建每个子Item之间的间隔Widget
      separatorBuilder: (BuildContext context, int index) {
        return new Divider();
      },
    );
  }
}

是不是很简单,但是懒加载确实是面试真题,你了解了吗?

ad.png

相关文章
|
8月前
|
前端开发 机器人 数据安全/隐私保护
Flutter笔记:手写并发布一个人机滑动验证码插件
写 Flutter 项目时,遇到需要滑块验证码功能。滑块验证码属于人机验证码的一种,看起来像是在一个图片中“挖去”了一块,然后通过用户手动操作滑块,让被“挖去”的部分移回来。由于我不想使用各种第三方模块,因此决定自己实现一个初版以后慢慢添砖加瓦。本文是对第一个版本的一点记录。
210 1
Flutter笔记:手写并发布一个人机滑动验证码插件
|
1月前
Flutter 小技巧之 ListView 和 PageView 的各种花式嵌套
Flutter 小技巧之 ListView 和 PageView 的各种花式嵌套 在 Flutter 中,ListView 和 PageView 是两个常用的控件,它们可以用于滑动展示大量内容的场景,且支持各种嵌套方式,本文将介绍其中的一些花式嵌套方式。
130 0
|
1月前
|
XML JSON 前端开发
【Flutter前端技术开发专栏】Flutter中的图片、视频与网络资源加载
【4月更文挑战第30天】Flutter是谷歌的开源前端框架,因其高性能、流畅UI和多端运行能力受开发者喜爱。本文聚焦于Flutter中的资源加载:使用`Image`组件加载静态、网络和本地图片;通过`video_player`库加载和播放视频;利用`http`包进行网络资源请求。掌握这些技巧将有助于提升Flutter应用的开发效率和质量。
【Flutter前端技术开发专栏】Flutter中的图片、视频与网络资源加载
|
1月前
Flutter.源码分析.flutter/packages/flutter/lib/src/widgets/scroll_view.dart/ListView
Flutter.源码分析.flutter/packages/flutter/lib/src/widgets/scroll_view.dart/ListView
37 0
|
1月前
|
UED
flutter笔记:骨架化加载器
flutter笔记:骨架化加载器
249 0
|
iOS开发 容器
重识Flutter 在不同的滑动列表场景,请选择合适的Slivers - part2
在Flutter中,碰到复杂的、不同的滑动业务场景,若是选择了一个合适的Slivers组件,那么我认为问题会变得简单!
重识Flutter 在不同的滑动列表场景,请选择合适的Slivers - part2
重识Flutter 用于解决复杂滑动视窗问题的Slivers - part1
在日常的开发工作中,仅仅使用ListView、ListView.builder等这样的滑动组件就能满足大部分的业务需求,但在碰到较为复杂的滑动页面时,我认为Slivers可以帮你更简单的实现。
重识Flutter  用于解决复杂滑动视窗问题的Slivers - part1
flutter系列之:flutter中listview的高级用法
一般情况下,我们使用Listview的方式是构建要展示的item,然后将这些item传入ListView的构造函数即可,通常情况下这样做是够用了,但是不排除我们会有一些其他的特殊需求。 今天我们会来讲解一下ListView的一些高级用法。
|
缓存
【布局 widget】Flutter ListView
ListView 是最常用的滚动 widget,也是布局 widget。它在滚动方向上一个接一个地显示它的 child。
216 0
【布局 widget】Flutter ListView
|
Dart IDE 开发工具
Flutter框架对热重载在项目里的深度运用,状态热重新加载以及静态字段被延迟初始化【Flutter】
Flutter框架对热重载在项目里的深度运用,状态热重新加载以及静态字段被延迟初始化【Flutter】