美文网首页
Flutter常用widget —— ListView

Flutter常用widget —— ListView

作者: 刘铁崧 | 来源:发表于2020-11-12 15:32 被阅读0次

构造方法有两种:

  1. 默认构造方法:ListView()
  2. 通过builder创建:ListView.build()
  3. 通过增加分割线方式创建:
ListView.separated(itemBuilder: null, separatorBuilder: null, itemCount: null);
  1. 通过自定义代理方式创建
 ListView.custom(childrenDelegate: null)

使用ListView()创建列表简单的使用案例
注:如果使用横向滚动必须设置itemExtent或指定宽度,否则报错

class _ESTestState extends State<ESTest> {
  @override
  Widget build(BuildContext context) {
    return ListView(
      itemExtent: 200,//设置内部元素最大宽度
      scrollDirection: Axis.horizontal,// 滚动方向
      children: List.generate(100, (index){
        // 遍历 100 个子元素
        return ListTile(
          leading: Icon(Icons.face),
          title: Text("标题 $index"),
          subtitle: Text("底部subtitle"),
          trailing: Icon(Icons.arrow_downward),
        );
      }),
    );
  }
}

使用builder创建列表的简单案例

class _ESTestState extends State<ESTest> {
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: 100,
      itemExtent: 60,
      itemBuilder:(BuildContext contex,int index){
        return Text("内部标题 $index",style: TextStyle(fontSize: 20));
      },
    );
  }
}

使用separatorBuilder创建列表的简单案例

class _ESTestState extends State<ESTest> {
  @override
  Widget build(BuildContext context) {
    return ListView.separated(
      itemCount: 100,
      cacheExtent: 80,//预加载高度
      itemBuilder: (BuildContext context,int index){
        return Text("标题+$index");
      },
      separatorBuilder: (BuildContext context,int index){//分割线
        return Divider(
          height: 10,//只是设置线所占区域的大小。设置线尺寸需要用thickness
          color: Colors.red,
          indent: 20,//前 预留宽度
          endIndent: 20,//后 预留宽度
          thickness: 2,// 线的高度
        );
      },
    );
  }
}

滚动监听

1. 通过controller进行监听

  • 可以设置默认值offset
  • 监听滚动,也可以监听滚动的位置


class _ESTestState extends State<ESTest> {
  ScrollController _controller = ScrollController(initialScrollOffset: 300);//初始滚动300距离的偏移量
  bool _showUpBtn = false;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _controller.addListener(() {
      print("监听滚动位置:${_controller.offset}");
      setState(() {
        _showUpBtn = _controller.offset > 20;
      });
    });
  }
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        ListView.builder(
          controller: _controller,
          itemBuilder: (BuildContext context,int index){
            return ListTile(
              leading: Text("测试 $index"),
            );
          },
        ),
        Positioned(
          right: 30,
          bottom: 30,
          child: _showUpBtn ? FloatingActionButton(
            child: Icon(Icons.thumb_up,color: Colors.white,),
            onPressed: (){
              _controller.animateTo(0, duration: Duration(seconds: 1), curve: Curves.easeInCubic);//动画调转
              // controller.jumpTo(0);//直接调转
            },
          ):Container(),
        )
      ],
    );
  }
}

2. 通过NotificationListener监听

  • 可以监听开始滚动,结束滚动


class _ESTestState extends State<ESTest> {
  ScrollController _controller = ScrollController(initialScrollOffset: 300);//初始滚动300距离的偏移量
  bool _showUpBtn = false;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _controller.addListener(() {
      // print("监听滚动位置:${_controller.offset}");
      setState(() {
        _showUpBtn = _controller.offset > 20;
      });
    });
  }
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        NotificationListener(
          onNotification: (ScrollNotification notification){
            if(notification is ScrollStartNotification){
              print("开始滚动监听");
            }
            else if(notification is ScrollUpdateNotification){
              print("正在滚动到${notification.metrics.pixels}位置\n最大滚动范围:${notification.metrics.maxScrollExtent}");
            }
            else if(notification is ScrollEndNotification){
              print("结束滚动");
            }
             return true;//true:向上冒泡 false:阻止冒泡
          },
          child: ListView.builder(
            controller: _controller,
            itemBuilder: (BuildContext context,int index){
              return ListTile(
                leading: Text("测试 $index"),
              );
            },
          ),
        ),

        Positioned(
          right: 30,
          bottom: 30,
          child: _showUpBtn ? FloatingActionButton(
            child: Icon(Icons.thumb_up,color: Colors.white,),
            onPressed: (){
              _controller.animateTo(0, duration: Duration(seconds: 1), curve: Curves.easeInCubic);//动画调转
              // controller.jumpTo(0);//直接调转
            },
          ):Container(),
        )
      ],
    );
  }
}

~注意:使用后调用析构函数将controller销毁(防止引用引起的内存泄漏)

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _controller.dispose();
  }

相关文章

网友评论

      本文标题:Flutter常用widget —— ListView

      本文链接:https://www.haomeiwen.com/subject/krjebktx.html