flutter基础:listview的使用

简介

listview是flutter中最常用的滚动组件之一,可以非常方便的实现一个方向上的多个子组件的线性排列。先看一下它的默认构造函数:

ListView({
    
    
    Key key,
    Axis scrollDirection = Axis.vertical,
    bool reverse = false,
    ScrollController controller,
    bool primary,
    ScrollPhysics physics,
    bool shrinkWrap = false,
    EdgeInsetsGeometry padding,
    this.itemExtent,
    bool addAutomaticKeepAlives = true,
    bool addRepaintBoundaries = true,
    bool addSemanticIndexes = true,
    double cacheExtent,
    List<Widget> children = const <Widget>[],
    int semanticChildCount,
    DragStartBehavior dragStartBehavior = DragStartBehavior.start,
    ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
    String restorationId,
    Clip clipBehavior = Clip.hardEdge,
  })
  • scrollDirection:列表滚动的方向,可选Axis.vertical、Axis.horizontal代表竖向滑动和横向滑动,默认竖向。
  • reverse:是否倒序显示 ,默认为正序显示。
  • controller:listview的控制器,可以用来监听滑动状态。
  • physics:physics有几个可选项,
AlwaysScrollableScrollPhysics() 总是可以滑动
NeverScrollableScrollPhysics() 禁止滚动
BouncingScrollPhysics() 内容超过一屏,拉到顶部有回弹效果
ClampingScrollPhysics() 包裹内容,不会有回弹
  • shrinkWrap:列表的长度是否只包裹其内容的长度,默认为false。注意,当listview包含于一个长度不确定的组件中必须设为true,否则将会报错。
  • children:存放子元素的组件数组。

简单介绍了一些常用的参数,下面来看一下常用的使用方法。

默认构造方法

默认构造方法的子元素是直接写在children列表里面的,它接受的是Widget。这种方式比较适合元素比较少的情况,对于子元素差异大的情况也很好用。

ListView(
  shrinkWrap: true, 
  padding: const EdgeInsets.all(20.0),
  children: <Widget>[
    new Text('item1'),
    new Text('item2'),
    new Text('item3'),
  ],
);

ListView.builder

  new ListView.builder(
              itemBuilder: (BuildContext context, int index) {
    
    
                return getItem(index);
              },
              itemCount: data.length,
              itemExtent: 50.0, //强制高度为50.0
              shrinkWrap: true,
              physics: BouncingScrollPhysics(),
            )
  • itemBuilder:子元素的构建器,参数有context和index(当前列表位置),返回值为一个widget。当列表滚动到具体的index位置时,会调用该构建器构建列表项。
  • itemCount:子项的数量,这里返回了测试数据的长度。当不使用此参数时listview元素是无限的。

重写initState方法,添加测试数据:

  List data = [];
  @override
  void initState() {
    
    
    super.initState();
    setState(() {
    
    
      for (int i = 0; i < 100; i++) {
    
    
        data.add("item $i");
      }
    });
  }

接着是构造子元素的getItem方法,这里使用了GestureDetector处理点击事件,toast则是使用了 fluttertoast: ^3.1.3包。

  Widget getItem(int index) {
    
    
    return new GestureDetector(
      onTap: () {
    
    
        //处理点击事件
        showToast(data[index]);
      },
      child: new Container(
        padding: const EdgeInsets.all(14.0),
        child: new Text(data[index]),
      ),
    );
  }

ListView.separated

ListView.separated与ListView.builder的主要区别是它提供了生成分割线的一个必填参数separatorBuilder,示例如下:

 new ListView.separated(
              itemBuilder: (BuildContext context, int index) {
    
    
                return getItem(index);
              },
              separatorBuilder: (BuildContext context, int index) {
    
    
                return new Divider(
                  endIndent: 50,
                  height: 1,
                  thickness: 1,
                );
              },
              itemCount: data.length,
              shrinkWrap: true,
              physics: ClampingScrollPhysics(),
            )

Divider即是分割线,参数有

  • height:分割线占用的高度

  • thickness:分割线的厚度。

  • indent:分割线起点端留白长度。

  • endIndent:分割线终点端留白长度。

  • color:线的颜色。

    另外:itemCount在这种模式下是必填参数,与ListView.builder不同。ListView.builder的方式要
    添加分割线的话可以在itemBuilder中添加(即添加到子元素中)。
    

完整示例

最后贴上完整的示例代码:

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:fluttertoast/fluttertoast.dart';

void main() {
    
    
  runApp(new ListViewApp());
}

class ListViewApp extends StatelessWidget {
    
    
  @override
  Widget build(BuildContext context) {
    
    
    // TODO: implement build
    return new MaterialApp(
      theme: ThemeData.light(),
      home: new ListViewWidget(),
      title: "listViewSample",
    );
  }
}

class ListViewWidget extends StatefulWidget {
    
    
  @override
  ListState createState() => new ListState();
}

class ListState extends State<ListViewWidget> {
    
    
  List data = [];

  @override
  void initState() {
    
    
    super.initState();
    setState(() {
    
    
      for (int i = 0; i < 100; i++) {
    
    
        data.add("item $i");
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    
    
    // TODO: implement build
    return new Scaffold(
        appBar: new AppBar(
          backgroundColor: Colors.blue,
          title: new Center(
            child: new Text('listViewTitle'),
          ),
        ),
        body: new Column(
          children: [

            new Expanded(
                child: new ListView.separated(
              itemBuilder: (BuildContext context, int index) {
    
    
                return getItem(index);
              },
              separatorBuilder: (BuildContext context, int index) {
    
    
                return new Divider(
                  endIndent: 50,
                  height: 1,
                  thickness: 1,
                );
              },
              itemCount: data.length,
              shrinkWrap: true,
              physics: ClampingScrollPhysics(),
            )),

          ],
        ));

     
  }

  Widget getItem(int index) {
    
    
    return new GestureDetector(
      onTap: () {
    
    
        //处理点击事件
        showToast(data[index]);
      },
      child: new Container(
        padding: const EdgeInsets.all(14.0),
        child: new Text(data[index]),
      ),
    );
  }

  void showToast(String toast) {
    
    
    Fluttertoast.showToast(
      msg: toast,
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.BOTTOM,
      timeInSecForIos: 1,
    );
  }
}

运行效果:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_40652755/article/details/109491469