flutter学习之Listview

ListView构造方法

ListView.separated({
    Key key,
    Axis scrollDirection = Axis.vertical,
    bool reverse = false,
    ScrollController controller,
    bool primary,
    ScrollPhysics physics,
    bool shrinkWrap = false,
    EdgeInsetsGeometry padding,
    @required IndexedWidgetBuilder itemBuilder,
    @required IndexedWidgetBuilder separatorBuilder,
    @required int itemCount,
    bool addAutomaticKeepAlives = true,
    bool addRepaintBoundaries = true,
    bool addSemanticIndexes = true,
    double cacheExtent,
  })
scrollDirection滑动方向
reverse是否按照阅读方向相反的方向滑动
controller此属性接受一个ScrollController对象。ScrollController的主要作用是控制滚动位置和监听滚动事件
primary指是否使用widget树中默认的PrimaryScrollController;当滑动方向为垂直方向(scrollDirection值为Axis.vertical)并且没有指定controller时,primary默认为true.
physics此属性接受一个ScrollPhysics类型的对象,它决定可滚动组件如何响应用户操作
shrinkWrap该属性表示是否根据子组件的总长度来设置ListView的长度,默认值为false
padding内边距
itemBuilder构建item widget
separatorBuilder构建分割线 widget
itemCountitem 的数据长度
addAutomaticKeepAlives默认true,该属性表示是否将列表项(子组件)包裹在AutomaticKeepAlive 组件中,如果将列表项包裹在AutomaticKeepAlive中,在该列表项滑出视口时它也不会被GC(垃圾回收),它会使用KeepAliveNotification来保存其状态。如果列表项自己维护其KeepAlive状态,那么此参数必须置为false。
addRepaintBoundaries默认true,该属性表示是否将列表项(子组件)包裹在RepaintBoundary组件中。当可滚动组件滚动时,将列表项包裹在RepaintBoundary中可以避免列表项重绘,但是当列表项重绘的开销非常小(如一个颜色块,或者一个较短的文本)时,不添加RepaintBoundary反而会更高效。
itemExtent滚动方向是垂直方向,则itemExtent代表子组件的高度;如果滚动方向为水平方向,则itemExtent就代表子组件的宽度。

一般来说,默认参数大多数情况下不需要改动

默认构造方法

默认构造函数有一个children参数,它接受一个Widget列表(List)。这种方式适合只有少量的子组件的情况

ListView(
          scrollDirection: Axis.vertical,
          shrinkWrap: true,
          children: <Widget>[
            Container(
              color: Colors.red,
              child: Text("春眠不觉晓"),
            ),
            Text("处处闻啼鸟"),
            Text("夜来风雨声"),
            Text("花落知多少"),
          ],
        ),

在这里插入图片描述

ListView.builder

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

class List2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return ListView.builder(
      itemBuilder: (BuildContext context, int index) {
        return ListTile(
          title: Text("标题"),
          subtitle: Text("副标题"),
          leading: Icon(Icons.add_a_photo),
          trailing: Text("2222"),
        );
      },
      scrollDirection: Axis.vertical,
      itemExtent: 50,
      itemCount: 50,
    );
  }
}

在这里插入图片描述

ListView.separated

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

class List3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return ListView.separated(
      itemBuilder: (BuildContext context, int index) {
        return ListTile(
          title: Text("标题"),
          subtitle: Text("副标题"),
          leading: Icon(Icons.add_a_photo),
          trailing: Text("2222"),
        );
      },
      separatorBuilder: (BuildContext context, int index) {
        return Divider(
          indent: 10,
          endIndent: 10,
          color: Colors.grey,
        );
      },
      itemCount: 50,
    );
  }
}

在这里插入图片描述

Divider 分割线
indent起点缩进距离
endIndent终点缩进距离
color分割线的颜色
height分割线区域的高度,并非分割线的高度
thickness分割线的厚度,真正的分割线的高度
实现分割线样式

可以通过逻辑运算,用分割线来实现分组标题

class List4 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    Widget divider = Container(
      color: Colors.blue,
      alignment: Alignment.center,
      padding: EdgeInsets.all(8),
      child: Text(
        "这是标题",
        style: TextStyle(fontSize: 24,color: Colors.white),
      ),
    );
    return ListView.separated(
      itemBuilder: (BuildContext context, int index) {
        return ListTile(
          title: Text("标题"),
          subtitle: Text("副标题"),
          leading: Icon(Icons.add_a_photo),
          trailing: Text("$index"),
        );
      },
      separatorBuilder: (BuildContext context, int index) {
        return index > 0 && index % 6 == 0
            ? divider
            : Divider(
                color: Colors.grey,
              );
      },
      itemCount: 50,
    );
  }
}

在这里插入图片描述

ListView item点击事件,item内部点击事件的实现

item的点击事件用手势widget,GestureDetector来实现,item内部点击事件用监听GestureDetector或者button的onpress(){}

class List5 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    Widget divider = Container(
      color: Colors.blue,
      alignment: Alignment.center,
      padding: EdgeInsets.all(8),
      child: Text(
        "这是标题",
        style: TextStyle(fontSize: 24, color: Colors.white),
      ),
    );

    return ListView.separated(
      itemBuilder: (BuildContext context, int index) {
        return GestureDetector(
          child: ListTile(
            title: Text("标题"),
            subtitle: Text("副标题"),
            leading: Icon(Icons.add_a_photo),
            trailing: IconButton(
              icon: Icon(Icons.arrow_forward_ios),
              onPressed: () {
                print("点击了返回按钮$index");
              },
            ),
          ),
          onTap: () {
            print("点击了$index");
          },
        );
      },
      separatorBuilder: (BuildContext context, int index) {
        return index > 0 && index % 6 == 0
            ? divider
            : Divider(
                color: Colors.grey,
              );
      },
      itemCount: 50,
    );
  }
}

在这里插入图片描述

demo

class List6 extends StatelessWidget {
  Widget divider = Container(
    color: Colors.blue,
    padding: EdgeInsets.all(8),
    child: Text(
      "这是标题",
      style: TextStyle(fontSize: 24, color: Colors.white),
    ),
  );

  Widget item = Container(
      margin: EdgeInsets.all(20),
      child: DecoratedBox(
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(6),
          border: Border.all(color: Colors.grey, width: 1),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            ClipRRect(
              borderRadius: BorderRadius.all(Radius.circular(6)),
              child: Image.network(
                "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574328399499&di=7ff1a40b7f76750091472b47e70d0a09&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201312%2F17%2F20131217205040_d5taC.jpeg",
              ),
            ),
            Padding(
              padding: EdgeInsets.all(20),
              child: Text("标题",style: TextStyle(
                fontSize: 24,
              ),),
            ),
            Padding(
              padding: EdgeInsets.fromLTRB(20,0,0,20),
              child: Text("这是一个副标题"),
            ),
          ],
        ),
      ));

  @override
  Widget build(BuildContext context) {
    // TODO: implement build

    return ListView.separated(
      itemBuilder: (BuildContext context, int index) {
        return GestureDetector(
          child: item,
          onTap: () {
            print("点击了$index");
          },
        );
      },
      separatorBuilder: (BuildContext context, int index) {
        return index > 0 && index % 6 == 0
            ? divider
            : Divider(
                color: Colors.grey,
              );
      },
      itemCount: 50,
    );
  }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值