前言:

今天就来介绍下Flutter中的列表组件ListView和网格组件GirdView,嗯,果然是Google家的亲儿子,连名字都和Android里的一模一样。
好的吧,我们还是来看下这两个Widget的用法吧

ListView

ListView就是我们常见的列表组件,在平时的应用开发中十分的常见,无论你做的是什么类型的应用都会多多少少会用到ListView,所以要好好看下这篇文章哦

还是先来看下listView的构造方法:
ListView({ Key key, Axis scrollDirection: Axis.vertical,//滚动方向 bool reverse:
false,//是否反向显示数据 ScrollController controller, bool primary, ScrollPhysics
physics,//物理滚动 bool shrinkWrap: false, EdgeInsetsGeometry padding, this
.itemExtent,//item有效范围 bool addAutomaticKeepAlives: true,//自动保存视图缓存 bool
addRepaintBoundaries:true,//添加重绘边界 List<Widget> children: const <Widget>[], })
那么,我们还是来看下具体的用法

我们还是按照惯例在Scaffold里放一个ListView
import 'package:flutter/material.dart'; class Routes extends StatelessWidget {
@override Widget build(BuildContext context) {return Scaffold( appBar:
AppBar(title: Text('目录')), body: new ListView( children: <Widget>[ ListTile(
title: Text('标题1'), leading: Icon(Icons.build), trailing: Text('尾巴'), onTap: ()
{ showDialog( context: context, child:new SimpleDialog( contentPadding: const
EdgeInsets.all(10.0), title: new Text("我是标题"), children: <Widget>[new Text(
"我是内容区域")], )); }, ), ListTile( title: Text('标题2'), leading: Icon(Icons.print),
trailing: Text('尾巴'), ), ListTile( title: Text('标题3'), leading:
Icon(Icons.library_music), trailing: Text('尾巴'), ), ListTile( title: Text('标题4'
), leading: Icon(Icons.accessibility_new), trailing: Text('尾巴'), ), ], ), ); } }
children参数我们传入了4个ListTile,先介绍下:
ListTile是一个固定高度的行,通常包含一些文本,以及一个行前或行尾图标。
const ListTile({ Key key, this.leading, this.title, this.subtitle, this
.trailing,this.isThreeLine = false, this.dense, this.contentPadding, this
.enabled =true, this.onTap, this.onLongPress, this.selected = false, }) : assert
(isThreeLine !=null), assert(enabled != null), assert(selected != null), assert
(!isThreeLine || subtitle !=null), super(key: key);
然后我们来看下效果


当然,由于数据量过少它现在是不能滑动的。大家可以在下面多加几个Widget试试效果。


在Flutter中有三种构建ListView的方式,刚才介绍的是最简单的一种,但是却不是最常用的,因为它仅仅适用于已知数量或者较少数量的Item的情况。如果有未知数量或者无限个Item的情况,再使用上述的方法将不再适用。

那么,我们可以尝试下ListView.builder()和ListView.custom()。


ListView.builder()和ListView.custom()的用法基本相同,只不过custom可以根据自己的需要控制Item显示方式,如Item显示大小。

我们今天来看下ListView.builder()
ListView.builder({ Key key, Axis scrollDirection = Axis.vertical, bool reverse
=false, ScrollController controller, bool primary, ScrollPhysics physics, bool
shrinkWrap =false, EdgeInsetsGeometry padding, this.itemExtent, @required
IndexedWidgetBuilder itemBuilder,//item构建者 int itemCount, //item数量 bool
addAutomaticKeepAlives =true, bool addRepaintBoundaries = true, double
cacheExtent, })
相比于new ListView()只不过多出了两个参数而已,一个是itemCount指定item的数量,一个是itemBuilder,用来构建Item。

看下用法
import 'package:flutter/material.dart'; class ListItem { final String title;
final IconData iconData; ListItem(this.title, this.iconData); } class
ListItemWidget extends StatelessWidget { final ListItem listItem;
ListItemWidget(this.listItem); @override Widget build(BuildContext context) {
return new ListTile( leading: new Icon(listItem.iconData), title: new
Text(listItem.title), ); } }class Routes extends StatefulWidget { @override
State<StatefulWidget> createState() {return RouteState(); } } class RouteState
extends State<Routes> { final List<ListItem> listData = []; @override void
initState() {super.initState(); for (int i = 0; i < 20; i++) {
listData.add(ListItem("我是测试标题$i", Icons.cake)); } } @override Widget
build(BuildContext context) {return Scaffold( appBar: AppBar( title: Text('列表'
), ), body: ListView.builder( itemBuilder: (BuildContext context,int index) {
return ListItemWidget(listData[index]); }, itemCount: listData.length, ), ); } }
我们首先新建了一个ListItem对象,icon和title两个属性
我们新建了一个一个Widget,需要传入ListItem对象,借助于ListItem对象的属性初始化ListTitle。
然后在initState方法中初始化listData,创建了20个ListItem对象。

在itemBuilder中返回指定的的Listitem到ListItemWidget对象中,返回指定的ListItemWidget对象。

通过这种方法,我们不需要关注Item的数量,因为我们每个Item都是自动构建的,并且大大减少重复代码的数量。

下面来看下GridView

GridView

GirView的用法和ListView类似,只不过由于GridView可以在一列或者一行显示多个Item,所以在构造方法中就多了个参数
GridView({ Key key, Axis scrollDirection = Axis.vertical, bool reverse = false
, ScrollController controller,bool primary, ScrollPhysics physics, bool
shrinkWrap =false, EdgeInsetsGeometry padding, @required this.gridDelegate,
//没错,它就是控制GridView的 bool addAutomaticKeepAlives = true, bool
addRepaintBoundaries =true, double cacheExtent, List<Widget> children = const
<Widget>[], })
看下gridDelegate参数

可以传入SliverGridDelegateWithFixedCrossAxisCount对象和
SliverGridDelegateWithMaxCrossAxisExtent对象。
其中SliverGridDelegateWithFixedCrossAxisCount可以直接指定每行(列)显示多少个Item,
SliverGridDelegateWithMaxCrossAxisExtent会根据GridView的宽度和你设置的每个的宽度来自动计算没行显示多少个Item
国际惯例,我们还是只介绍一个,那就SliverGridDelegateWithFixedCrossAxisCount吧。

看下代码,怎么用
import 'package:flutter/material.dart'; class GridViewPage extends
StatelessWidget { @override Widget build(BuildContext context) { return
Scaffold( appBar: AppBar( title: Text('GridView'), ), body: GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount:2,
//每行2个 mainAxisSpacing: 10.0, //主轴(竖直)方向间距 crossAxisSpacing: 10.0, //纵轴(水平)方向间距
childAspectRatio:1.0 //纵轴缩放比例 ), children: <Widget>[ Container( alignment:
Alignment.center, color: Colors.green, child: Image.asset("images/pic1.jpg"),
), Container( alignment: Alignment.center, color: Colors.green, child:
Image.asset("images/pic1.jpg"), ), Container( alignment: Alignment.center,
color: Colors.green, child: Image.asset("images/pic1.jpg"), ), Container(
alignment: Alignment.center, color: Colors.green, child: Image.asset(
"images/pic1.jpg"), ), Container( alignment: Alignment.center, color:
Colors.green, child: Image.asset("images/pic1.jpg"), ), Container( alignment:
Alignment.center, color: Colors.green, child: Image.asset("images/pic1.jpg"),
), Container( alignment: Alignment.center, color: Colors.green, child:
Image.asset("images/pic1.jpg"), ), ], ), ); } }

和ListView类似,我们在GridView的children中新增了7个图片并给它设置背景并居中,另外我们根据gridDelegate属性设置每行显示2个Item,并且设置Item间隔为10像素。

效果如下:

当然,GridView你也可以使用builder()和custom()的方式实现
import 'package:flutter/material.dart'; class GridViewPage extends
StatefulWidget { @override State<StatefulWidget> createState() { return
GridViewState(); } }class GridViewState extends State<GridViewPage> { final
List<ListItem> listData = []; @overridevoid initState() { super.initState(); for
(int i = 0; i < 20; i++) { listData.add(new ListItem("我是测试标题$i", Icons.cake));
} } @override Widget build(BuildContext context) {return Scaffold( appBar:
AppBar( title: Text('GridView'), ), body: GridView.builder( gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount:2, //每行2个
mainAxisSpacing:10.0, //主轴(竖直)方向间距 crossAxisSpacing: 10.0, //纵轴(水平)方向间距
childAspectRatio:1.0 //纵轴缩放比例 ), itemCount: listData.length, itemBuilder:
(BuildContext context,int index) { return ListItemWidget(listData[index]); },
), ); } }class ListItem { final String title; final IconData iconData; ListItem(
this.title, this.iconData); } class ListItemWidget extends StatelessWidget {
final ListItem listItem; ListItemWidget(this.listItem); @override Widget
build(BuildContext context) {return new GestureDetector( child: new Container(
color: Colors.green, child:new Column( mainAxisAlignment:
MainAxisAlignment.center, children: <Widget>[new Icon( listItem.iconData, size:
50.0, color: Colors.white, ), new Text( listItem.title, style: TextStyle(color:
Colors.white), ) ], ), ), onTap: () { Scaffold.of(context).showSnackBar(new
SnackBar( content:new Text(listItem.title), )); }, ); } }
和上面ListView的用类似,只不过我们现在是一行显示多个Item而已。并且我们给每个Item设置上了点击事件,每次点击Item就会弹出相应的标题。


小结

*
ListView就是我们常用的列表视图

*
GridView就是我们常用的宫格视图

*
ListView和GridView都可以使用new 或者builder()和custom()方法来创建对象

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信