Flutter组件ListView

ListView是最常用的可滚动组件之一,它可以沿一个方向线性排布所有子组件,并且它也支持基于Sliver的延迟构建模型。

属性:

itemExtent:

该参数如果不为null,则会强制children的“长度”为itemExtent的值;这里的“长度”是指滚动方向上子组件的长度,也就是说如果滚动方向是垂直方向,则itemExtent代表子组件的高度;如果滚动方向为水平方向,则itemExtent就代表子组件的宽度。

shrinkWrap:

该属性表示是否根据子组件的总长度来设置ListView的长度,默认值为false 。默认情况下,ListView的会在滚动方向尽可能多的占用空间。

addAutomaticKeepAlives:

该属性表示是否将列表项(子组件)包裹在AutomaticKeepAlive 组件中;如在一个懒加载列表中,将列表项包裹在AutomaticKeepAlive中,在该列表项滑出视口时它也不会被回收,它会使用KeepAliveNotification来保存其状态。

addRepaintBoundaries:

该属性表示是否将列表项(子组件)包裹在RepaintBoundary组件中。当可滚动组件滚动时,将列表项包裹在RepaintBoundary中可以避免列表项重绘。

默认构造函数

默认构造函数有一个children参数,它接受一个Widget列表(List)。这种方式适合只有少量的子组件的情况,因为要将所有children都提前创建好,而不是等到子widget真正显示的时候再创建。

重要:可滚动组件通过一个List来作为其children属性时,只适用于子组件较少的情况。

ListView(
  shrinkWrap: true,
  padding: const EdgeInsets.all(10),
  children: <Widget>[
    Text("佛山无影脚"),
    Text("南拳北腿"),
    Text("少林武当"),
    Text("峨眉倥侗"),
    Text("武林盟主"),
  ],
),

在这里插入图片描述

ListView.builder

ListView.builder适合列表项比较多(或者无限)的情况,因为只有当子组件真正显示的时候才会被创建,也就说通过该构造函数创建的ListView是支持基于Sliver的懒加载模型的。

属性

itemBuilder:它是列表项的构建器,类型为IndexedWidgetBuilder,返回值为一个widget。
	当列表滚动到具体的index位置时,会调用该构建器构建列表项。
itemCount:列表项的数量,如果为null,则为无限列表。
ListView.builder(
  itemCount: 80,
  scrollDirection: Axis.vertical,
  itemExtent: 50,//限制高度为50
  itemBuilder: (BuildContext context,int index){
    return ListTile(title: Text("$index",),minLeadingWidth: double.infinity,);
  },
),

如图
在这里插入图片描述

ListView.separated

ListView.separated可以在生成的列表项之间添加一个分割组件,它比ListView.builder多了一个separatorBuilder参数,该参数是一个分割组件生成器。

Widget blueDivider = Divider(color: Colors.blue,);
Widget greenDivider = Divider(color: Colors.green,);
Widget separated = ListView.separated(
    itemBuilder: (BuildContext context,int index){
      return ListTile(title: Text("$index",),minLeadingWidth: double.infinity,);
    },
    separatorBuilder: (BuildContext context,int index){
      return index%2 == 0?blueDivider:greenDivider;
    },
    itemCount: 80,
);

效果
在这里插入图片描述

实现无限加载列表

从数据源异步分批拉取一些数据,然后用ListView展示,当我们滑动到列表末尾时,判断是否需要再去拉取数据,如果是,则去拉取,拉取过程中在表尾显示一个loading,拉取成功后将数据插入列表;如果不需要再去拉取,则在表尾提示"没有更多"。

代码

class InfiniteListView extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return InfiniteListViewState();
  }
}
class InfiniteListViewState extends State<InfiniteListView>{
  static const loadingTag = "##loading##"; //表尾标记
  var words = <String>[loadingTag];
  @override
  void initState() {
    super.initState();
    getData();
  }


  @override
  Widget build(BuildContext context) {
    return ListView.separated(
      itemBuilder: (BuildContext context,int index){
        if(words[index] == loadingTag){
          if(words.length-1 < 100){
            //小于100 继续添加数据
            getData();
            //加载是显示loading
            return Container(
              alignment: Alignment.center,
              padding: const EdgeInsets.all(10),
              child: SizedBox(
                width: 36,
                height: 36,
                child: CircularProgressIndicator(strokeWidth: 2,),
              ),
            );
          }else{
            //大于等于100,不再添加数据
            return Container(
              alignment: Alignment.center,
              padding: const EdgeInsets.all(10),
              child: Text("没有更多了",style: TextStyle(color: Colors.grey),),
            );
          }
        }
        return ListTile(title: Text(words[index]),);
      },
      separatorBuilder: (BuildContext context,int index){
        return Divider(height: 1,);
      },
      itemCount: words.length,
    );
  }
  //生成数据
  void getData() {
    Future.delayed(Duration(seconds: 2)).then((value){
      setState(() {
        //重新加列表
        words.insertAll(words.length-1,
          //每次生成10个单词
          generateWordPairs().take(10).map((e) => e.asPascalCase).toList()
        );
      });
    });
  }

}

单词生成包的引入
1,pubspec.yaml中 添加 english_words: ^4.0.0,
2,导包import ‘package:english_words/english_words.dart’;

效果
在这里插入图片描述在这里插入图片描述

添加固定列表头

class StudyListView extends StatelessWidget{
  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text("ListView"),
      ),
      body: Scrollbar(//显示滚动条
        child: Column(
          children: <Widget>[
            ListTile(title:Text("单词表")),
            Expanded(child: InfiniteListView()),
          ],
        ),
      ),
    );
  }

}

如图
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值