Flutter ListView源码分析

187 阅读3分钟

ListView是最常用的滑动组件

构建ListView

ListView(): 在item每没有出现在屏幕就会创建,性能开销比较大,可能会引起卡顿,所以不适合长列表 ListView.build(): 最长使用的列表 **ListView.separated():**处理分割线

1.ListView()基础构造

 @override
  Widget build(BuildContext context) {
    return Container(
      height: 200,
      child: ListView(
        children: data
            .map((color) => Container(
          alignment: Alignment.center,
          width: 100,
          height: 50,
          color: color,
        ))
            .toList(),
      ),
    );
  }

构造属性

在这里插入图片描述

  • scrollDirection :列表的滚动方向 Axis的horizontal和vertical分为横向和竖直 默认是竖直
  • reverse :是否翻转 默认是不反转
  • ScrollController: 用来控制滚动位置及监听滚动事件
  • primary : primary为true时,我们的ScrollController 无效
  • ScrollPhysics 用来控制滑动的效果的(AlwaysScrollableScrollPhysics() ,NeverScrollableScrollPhysics(),BouncingScrollPhysics(),ClampingScrollPhysics())
  • shrinkWrap: 是否根据子widget的总长度来设置ListView的长度,该属性将决定列表的长度是否仅包裹其内容的长度。当ListView嵌在一个无限长的容器组件中时,shrinkWrap必须为true
  • itemExtent :子元素长度。当列表中的每一项长度是固定的情况下可以指定该值,有助于提高列表的性能(因为它可以帮助ListView在未实际渲染子元素之前就计算出每一项元素的位置);
  • cacheExtent: 预渲染区域长度,预加载的区域。ListView会在其可视区域的两边留一个cacheExtent长度的区域作为预渲染区域(对于ListView.build或ListView.separated构造函数创建的列表,不在可视区域和预渲染区域内的子元素不会被创建或会被销毁),设置预加载的区域 cacheExtent 强制设置为了 0.0,从而关闭了“预加载”;
  • addAutomaticKeepAlives:该字段表示是否将列表项包裹在AutomaticKeepAlive Widget中,默认为true,效果就是,列表子widget滑出可见视图时,其状态还会被保持,数据还会保持,并且列表项不会被GC掉
  • addRepaintBoundaries:表示是否将列表项包裹在RepaintBoundary中,默认为true,如果包裹则列表项不会重绘

2. ListView.builder构建

构造属性在这里插入图片描述

  • itemCount: 列表中元素的数量,如果为null,则表示无限列表
  • itemBuilder: 子元素的渲染方法,允许自定义子元素组件。列表项的构建器,类型为IndexedWidgetBuilder,返回值为一个widget(就是一个组件)。 当列表滚动到具体的index位置时,会调用该构建器构建列表项,也就是所谓的基于Sliver的懒加载模型。
  • itemExtent:children的“长度” 如果滚动方向是垂直方向,则itemExtent代表子组件的高度; 如果滚动方向为水平方向,则itemExtent就代表子组件的宽度。
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 200,
      child: ListView.builder(
        itemCount: data.length,
        itemBuilder: (context, index) => _buildItem(data[index]),
      ),
    );
  }

3. ListView.separated构建

构造参数 在这里插入图片描述

  • separatorBuilder:只多了一个参数,就是为了自定义分割线的
 @override
  Widget build(BuildContext context) {
    return Container(
      height: 200,
      child: ListView.separated(
        separatorBuilder: (context, index) => Divider(
          thickness: 1,
          height: 1,
          color: Colors.orange,
        ),
        itemCount: data.length,
        itemBuilder: (context, index) => _buildItem(data[index]),
      ),
    );
  }

GrideView 差不多

CustomScrollView 一种高级的listview 配合其他空间可以实现靓的效果