注册

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

前言:为了更好的减小网络的带宽,使得列表更加流畅,我们需要了解懒加载,也称延迟加载。 面试真题: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


作者:阿Tya
链接:https://juejin.cn/post/7012162051686531079
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册