Flutter 滚动列表 ListView 图文示例

ListView、ListView.builder

这是ListView的两个构造函数,ListView构造函数在列表布局少的时候使用,ListView.builder在渲染列表数据多的时候有优势。

  ListView({
    Key key,
    Axis scrollDirection = Axis.vertical,//设置滑动方向 Axis.horizontal 水平  默认 Axis.vertical 垂直
    bool reverse = false,//是否倒序显示 默认正序 false  倒序true
    ScrollController controller,//滑动监听
    bool primary,//false,如果内容不足,则用户无法滚动 而如果[primary]为true,它们总是可以尝试滚动。
    ScrollPhysics physics,//列表滚动至边缘后继续拖动的物理效果
    bool shrinkWrap = false,//child 高度会适配 item填充的内容的高度,
    EdgeInsetsGeometry padding,// 列表内边距
    this.itemExtent,//确定每一个item的高度 会让item加载更加高效
    bool addAutomaticKeepAlives = true,
    bool addRepaintBoundaries = true,
    bool addSemanticIndexes = true,
    double cacheExtent,//cacheExtent  设置预加载的区域
    List<Widget> children = const <Widget>[],// 列表内容
    int semanticChildCount,
    DragStartBehavior dragStartBehavior = DragStartBehavior.start,
  })

ListView.builder 的构造函数基本和 ListView 一致,仅多了个字段 int itemCount, 表示列表数据的数量

ListView 使用

在这里插入图片描述

Widget _buildListView() {

      return ListView(
        scrollDirection: Axis.horizontal,
        itemExtent: 140, //item延展尺寸(宽度)
        children: [
          //设置ListTile组件的标题与图标
          ListTile(leading: Icon(Icons.map), title: Text('Map')),
          ListTile(leading: Icon(Icons.mail), title: Text('Mail')),
          ListTile(leading: Icon(Icons.message), title: Text('Message')),
        ]
      );
    }

ListView.builder 使用

在这里插入图片描述

 ListView.builder(
          itemCount: 100,// 100 条数据
          itemExtent: 50.0,// 每条数据的高度是50
          itemBuilder: (BuildContext context, int index) {
           // 每条数据使用 ListTile 渲染
            return ListTile(title: Text("$index"));
          }
      );

ListTile

ListTileFlutter 提供的widget ,通过查看参数去了解这个widget能实现哪些功能。

  const ListTile({
    Key key,
    this.leading,// item 前置图标
    this.title, // item 标题
    this.subtitle,// item 副标题
    this.trailing,// item 后置图标
    this.isThreeLine = false,// item 是否三行显示
    this.dense,
    this.contentPadding,// item 内容内边距
    this.enabled = true,// item 是否可用
    this.onTap,// item onTap 点击事件
    this.onLongPress,// item onLongPress 长按事件
    this.selected = false,// item 是否选中状态
  })

在这里插入图片描述
伪代码如下:

ListView.builder(
    itemCount: 100,
    itemExtent: 50.0,
    itemBuilder: (BuildContext context, int index) {
      return ListTile(
          title: Text("$index"),
        subtitle: Text("subtitle $index"),
        leading: Icon(Icons.favorite),
        trailing: Icon(Icons.delete),
      );
    }
);

ListView.separated 分割线

在列表中经常会增加分割线来区分每一个 Item区域,在Flutter中也提供了ListView.separated构造方法实现。

效果图:分割线高度为5 ,且 index 为偶数, 创建绿色分割线,index为奇数, 则创建红色分割线

在这里插入图片描述

ListView.separated(
    itemCount: 100,
    //分割器构造器,高度为5 ,index 为偶数, 创建绿色分割线, index为奇数, 则创建红色分割线
    separatorBuilder: (BuildContext context, int index){
      return index %2 == 0 ? Divider(thickness:5.0, color: Colors.green) : Divider(thickness:5.0, color: Colors.red);
    },
    //列表项构造器
    itemBuilder: (BuildContext context, int index) {
      return ListTile(
        title: Text("$index"),
        subtitle: Text("subtitle $index"),
        leading: Icon(Icons.favorite),
        trailing: Icon(Icons.delete),
      );
    }
);

一般列表中我们都会有添加 上拉加载下拉刷新 的功能,有的页面布局还会增加头部和尾部

扫描二维码关注公众号,回复: 10017403 查看本文章

上拉加载 的功能在ListView可以通过监听列表滑动来实现。

下拉刷新的功能可以结合RefreshIndicator这个组件来实现。

头部和尾部的功能主要是通过判断ListViewitem的位置来动态添加widget,具体可参考这篇文章Flutter 之列表和头部 (ListView + Header),或者使用CustomScrollView组件实现。

第三方库推荐

下面仅使用flutter_easyrefresh做示例。

上下拉加载数据

在这里插入图片描述

  1. 引入该库:
dependencies:
  flutter_easyrefresh: ^2.0.9
  1. 使用例子
class EasyRefreshPage extends StatefulWidget {
  @override
  _EasyRefreshPageState createState() {
    return _EasyRefreshPageState();
  }
}

class _EasyRefreshPageState extends State<EasyRefreshPage> {

  EasyRefreshController _controller;
  // 条目总数
  int _count = 20;
  // 数据已全部加载完成
  bool _enableControlFinish = false;

  @override
  void initState() {
    super.initState();
    _controller = EasyRefreshController();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
        appBar: AppBar(
          title: Text('上拉加载、下拉刷新'),
        ),
        body: Center(
          child: Container(
            child: EasyRefresh.custom(
              controller: _controller,
              onRefresh:() async {
                await Future.delayed(Duration(milliseconds: 200), () {
                  if (mounted) {
                    setState(() {
                      _count = 20;
                    });
                  }
                });
              },
              onLoad:  () async {
                await Future.delayed(Duration(milliseconds: 200), () {
                  if (mounted) {
                    setState(() {
                      _count += 20;
                    });
                    // 数据全部加载完成
                    if (!_enableControlFinish) {
                      _controller.finishLoad(noMore: _count >= 40);
                    }
                  }
                });
              },
              slivers: <Widget>[
                SliverList(
                  delegate: SliverChildBuilderDelegate(
                        (context, index) {
                      return ListTile(
                        title: Text('$index'),
                      );
                    },
                    childCount: _count,
                  ),
                ),
              ],
            ),
          ),
        ),
    );
  }
}

完~

发布了180 篇原创文章 · 获赞 76 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/ITxiaodong/article/details/104947409