Flutter基础(七)Scrolling Widget之ListView、GridView、PageView

本文首发于公众号「刘望舒」

ReactNative入门系列 React Native组件 Flutter基础系列

前言

我们知道Widget的分类有很多种,比如:Basics、Material Components、Cupertino、Scrolling等等,在前面的文章我介绍了Basics和Material Components,这一篇讲一下Scrolling分类中比较常用的ListView、GridView、PageView。

1 ListView

ListView可以说是Flutter中最常用的Scrolling Widget。 ListView有四种构造函数:

  1. 默认构造函数ListView。
  2. ListView.builder,适用于具有大量(或无限)列表项。
  3. ListView.separated,可以配置分割线,适用于具有固定数量列表项的ListView。
  4. ListView.custom,提供了自定义子Widget的能力。
1.1 默认构造函数

用默认构造函数的方式来实现一个简单的列表。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('ListView示例'),
        ),
        body: ListView(
          children: <Widget>[
            ListTile(
              leading: Icon(Icons.access_time),
              title: Text('第1行'),
            ),
            ListTile(
              leading: Icon(Icons.access_time),
              title: Text('第2行'),
            ),
          ],
        ),
      ),
    );
  }
}
复制代码

ListTile是Material Components中的Widget,通常用于填充ListView,可以满足基本的图片+文字的列表需求。

1.2 ListView.builder创建

如果要展示大量列表项,可以使用ListView.builder。

import 'package:flutter/material.dart';

void main() => runApp(MyApp(
      items: new List<String>.generate(300, (i) => "第$i行"), //1
    ));

class MyApp extends StatelessWidget {
  final List<String> items;

  MyApp({@required this.items});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('ListView示例'),
        ),
        body: ListView.builder( //2
          itemCount: items.length,
          itemBuilder: (context, index) {
            return ListTile(
              leading: Icon(Icons.access_time),
              title: Text('${items[index]}'),
            );
          },
        ),
      ),
    );
  }
}
复制代码

在注释1生成300个数据,并将其传入到MyApp中,注释2处通过ListView.builder创建ListView,最终会通过ListTile来显示每一个列表项。

1.3 ListView.separated创建
import 'package:flutter/material.dart';

void main() => runApp(MyApp(
      items: new List<String>.generate(300, (i) => "第$i行"), 
    ));

class MyApp extends StatelessWidget {
  final List<String> items;

  MyApp({@required this.items});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Test',
      home: Scaffold(
        appBar: AppBar(
          title: Text('ListView示例'),
        ),
        body: ListView.separated(
          itemCount: items.length,
          itemBuilder: (context, index) {
            return ListTile(
              leading: Icon(Icons.access_time),
              title: Text('${items[index]}'),
            );
          },
          separatorBuilder: (context, index) {//1
            return Container(
              constraints: BoxConstraints.tightFor(height: 1),
              color: Colors.black45,
            );
          },
        ),
      ),
    );
  }
}

复制代码

这种创建方式和ListView.builder类似,有个最大的不同就是可以通过注释1处的separatorBuilder来设置分割线以及分割线的样式。

2 GridView

GridView的使用方法和ListView类似,它有五种构造函数:

  1. 默认构造函数GridView。
  2. GridView.count:在横轴方向上具有固定数量的GridView。
  3. GridView.extent:在横轴方向上具有最大范围的GridView。
  4. GridView.builder:适用于具有大量(或无限)列表项。
  5. GridView.custom:提供了自定义子Widget的能力。

这里以第2种构造函数为例。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: new Text('GridView示例'),
        ),
        body: GridView.count(
          crossAxisCount: 3, //1
          children: <Widget>[
            ListTile(
              title: Text('item1'),
            ),
            ListTile(
              title: Text('item2'),
            ),
            ListTile(
              title: Text('item3'),
            ),
            ListTile(
              title: Text('item4'),
            ),
            ListTile(
              title: Text('item5'),
            ),
            ListTile(
              title: Text('item6'),
            ),
            ListTile(
              title: Text('item7'),
            ),
            ListTile(
              title: Text('item8'),
            ),
            ListTile(
              title: Text('item9'),
            ),
          ],
        ),
      ),
    );
  }
}

复制代码

注释1处的crossAxisCount用于设置横轴item的数量。效果如下图所示:

3 PageView

PageView是一个可逐页滚动的列表,和Android中ViewPage类似。 PageView有三种构造函数:

  1. 默认构造函数PageView
  2. PageView.builder:适用于具有大量(或无限)列表项。
  3. PageView.custom:提供了自定义子Widget的能力。

以默认构造函数为例,代码如下所示。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('PageView示例'),
        ),
        body: PageView(
          onPageChanged: (index) {//1
            print('当前为第 $index 页');
          },
          children: <Widget>[
            ListTile(
              title: Text('第0页'),
            ),
            ListTile(
              title: Text('第1页'),
            ),
            ListTile(
              title: Text('第2页'),
            ),
          ],
        ),
      ),
    );
  }
}
复制代码

通过注释1处的onPageChanged属性可以得知当前滑动到了第几页。

总结

本文并没有介绍每个Widget的构造函数,那样的话就不是一篇文章能写下的了,也没有必要,我们掌握了其中一种构造函数基本就可以举一反三了。Scrolling Widget还包含了一些其他Widget,比如:NestedScrollView、Scrollbar、CustomScrollView、NotificationListener等等,就需要去自行查看官方文档了:flutter.dev/docs/develo…


这里不仅分享大前端、Android、Java等技术,还有程序员成长类文章。

转载于:https://juejin.im/post/5d2c9df8e51d45777540fe5e

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在层级组件Stack中,当键盘TextField的输入框获取焦点时,由于软键盘的弹出,可能会导致内容被顶上去的情况。解决这个问题的方法很简单,只需要在Stack组件中添加一个属性resizeToAvoidBottomInset并设置为false即可。这样做可以防止键盘弹出时内容被顶上去。例如: ```dart Stack( resizeToAvoidBottomInset: false, children: \[ // 其他组件 TextField(), // 其他组件 \], ) ``` 通过设置resizeToAvoidBottomInset为false,可以确保键盘弹出时不会影响到Stack中的其他组件的位置。这样就解决了软键盘弹出时提高ListView的问题。\[1\] #### 引用[.reference_title] - *1* *3* [【Flutter 问题系列第 16 篇】如何防止软键盘弹出后顶掉内容](https://blog.csdn.net/qq_42351033/article/details/116091208)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [正确使用FlutterListview](https://blog.csdn.net/qq_41628942/article/details/129127387)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值