ListView
参数认知
列举一下ListView
常用的参数:
参数名 | 参数说明 |
---|---|
scrollDirection | Axis.vertical竖向滑动,Axis.horizontal 横向滑动 |
padding | 表示内边距 |
reverse | 组件反向排序 |
children | l列表元素 |
ListView
基本使用
ListView
的基本使用。
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'ListView组件的学习',
home: Scaffold(
appBar: AppBar(title: Text('ListView组件的学习')),
body: BaseListView(),
),
);
}
}
class BaseListView extends StatelessWidget{
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
Image.network('http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png'),
Image.network('https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2344319804,963424543&fm=26&gp=0.jpg'),
Image.network('http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png'),
Image.network('https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2344319804,963424543&fm=26&gp=0.jpg'),
Image.network('http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png'),
Image.network('https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2344319804,963424543&fm=26&gp=0.jpg'),
Image.network('http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png'),
Image.network('https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2344319804,963424543&fm=26&gp=0.jpg'),
Image.network('http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png'),
Image.network('https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2344319804,963424543&fm=26&gp=0.jpg'),
],
);
}
}
效果如下:
上述效果看起来很low,所以我们添加一些元素,使其可以看得过眼
代码语言:javascript复制class ListViewWidgetTest extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: ListView(
padding: EdgeInsets.all(10),
children: <Widget>[
Image.network('http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png'),
Center(
child: Container(
alignment: Alignment.center,
color: Colors.cyanAccent,
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Text('无中生有'),
),
),
Image.network('https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2344319804,963424543&fm=26&gp=0.jpg'),
Center(
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Text('无中生有'),
),
),
Image.network('http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png'),
Center(
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Text('无中生有'),
),
),
Image.network('https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2344319804,963424543&fm=26&gp=0.jpg'),
Center(
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Text('无中生有'),
),
),
Image.network('http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png'),
Center(
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Text('无中生有'),
),
),
Image.network('https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2344319804,963424543&fm=26&gp=0.jpg'),
Center(
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Text('无中生有'),
),
),
Image.network('http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png'),
Center(
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Text('无中生有'),
),
),
Image.network('https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2344319804,963424543&fm=26&gp=0.jpg'),
Center(
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Text('无中生有'),
),
),
Image.network('http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png'),
Center(
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Text('无中生有'),
),
),
Image.network('https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2344319804,963424543&fm=26&gp=0.jpg'),
Center(
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.fromLTRB(0, 10, 0, 10),
child: Text('无中生有'),
),
),
],
),
);
}
}
其效果如下:
ListView
与结合ListTile
使用
直接上代码
代码语言:javascript复制void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'ListView组件的学习',
home: Scaffold(
appBar: AppBar(title: Text('ListView组件的学习')),
body: BaseListView(),
),
);
}
}
class BaseListView extends StatelessWidget{
@override
Widget build(BuildContext context) {
String _pathLeft='http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png';
String _pathRight='https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2344319804,963424543&fm=26&gp=0.jpg';
return ListView(
padding: EdgeInsets.all(10),
children: <Widget>[
ListTile(
leading: Icon( //leading设置左侧的的小部件,一般使用Icon或者Image
Icons.map, //Icon图标
color: Colors.cyanAccent, //设置Icon颜色
size: 20, //设置Icon大小
semanticLabel: 'Icon', //设置Icon的语义
),
trailing: Image.network(_pathRight), //设置右侧的小部件,一般使用Icon或者Image
title: Text('这是头部'),
subtitle: Text('这是身体'),
),
],
);
}
}
效果如下:
注意事项:
我们先来看看代码,从代码中可以看到我们只给Contaniner
组件设置宽高,按照我们所想,应该呈现出来的是宽高为100的一个正方形Item,但是该代码运行结果如下图所示:
class ListViewWidgetTest extends StatelessWidget {
@override
Widget build(BuildContext context) {
return
ListView(
padding: EdgeInsets.all(10),
children: <Widget>[
Container(
color: Colors.red,
width: 100,
height: 100,
),
Container(
color: Colors.blue,
width: 100,
height: 100,
),
Container(
color: Colors.amber,
width: 100,
height: 100,
),
Container(
color: Colors.red,
width: 100,
height: 100,
),
Container(
color: Colors.blue,
width: 100,
height: 100,
),
Container(
color: Colors.amber,
width: 100,
height: 100,
), Container(
color: Colors.red,
width: 100,
height: 100,
),
Container(
color: Colors.blue,
width: 100,
height: 100,
),
Container(
color: Colors.amber,
width: 100,
height: 100,
),
]
);
}
}
那么问题来了,如果我们想要实现一个宽高为100的item怎么办?
这个很简单,我们只需要将ListView
给定高度即可。
这里得提一下,我们的ListView
没有宽高属性,所以我们需要控制它的上级组件的宽高,从而控制ListView
的宽高
代码如下:
class ListViewWidgetTest extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
width: 100,
child: ListView(
children: <Widget>[
Container(
color: Colors.red,
height: 100,
),
Container(
color: Colors.blue,
height: 100,
),
Container(
color: Colors.amber,
height: 100,
),
Container(
color: Colors.red,
height: 100,
),
Container(
color: Colors.blue,
height: 100,
),
Container(
color: Colors.amber,
height: 100,
), Container(
color: Colors.red,
height: 100,
),
Container(
color: Colors.blue,
height: 100,
),
Container(
color: Colors.amber,
height: 100,
),
]
),
);
}
}
你可能会发现这部分代码中为什么,不去设置子item的布局宽度?这是因为我们ListView
竖直方向中,我们的子item
宽度是跟随ListView
的宽度。所以我们只需要设置子item
的高度即可
在没有给
ListView
设置宽高时,单纯的给ListView
中item
设置宽高时无效的,其效果会填满整个屏幕。我们应该判断ListView
为横向还是竖向,再去设置宽度或者高度。
ListView
的横向滑动(水平列表)
我们根据上面所学知识写一个item宽高为100的横向列表
代码语言:javascript复制class HorizontalListView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
height: 100,
child: ListView(scrollDirection: Axis.horizontal, children: <Widget>[
Container(
color: Colors.red,
width: 100,
),
Container(
color: Colors.blue,
width: 100,
),
Container(
color: Colors.amber,
width: 100,
),
Container(
color: Colors.red,
width: 100,
),
Container(
color: Colors.blue,
width: 100,
),
Container(
color: Colors.amber,
width: 100,
),
Container(
color: Colors.red,
width: 100,
),
Container(
color: Colors.blue,
width: 100,
),
Container(
color: Colors.amber,
width: 100,
),
]),
);
}
}
效果展示:
数据装填进阶使用
我们将ListView
中的children
抽离成为一个方法,这样就不会显得这么臃肿。
class ListViewTest extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return ListView(
children: _getData(),
);
}
List<Widget> _getData() {
return [
ListTile(
title: Text('我是一个列表'),
),
ListTile(
title: Text('我是一个列表'),
),
ListTile(
title: Text('我是一个列表'),
),
ListTile(
title: Text('我是一个列表'),
),
ListTile(
title: Text('我是一个列表'),
),
];
}
}
循环添加数据
代码语言:javascript复制class ListViewTest extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return ListView(
children: _getData(),
);
}
List<Widget> _getData() {
List<Widget> list=new List<Widget>();
for(int i=0;i<20;i ){
list.add(ListTile(
title: Text(
'这是第$i标题',
),
));
}
return list;
}
}
效果如下:
进行json
解析数据,并且展示到ListView
这种
首先我们创建一个名为listData.dart
文件,然后用于存放我们的json
数据
List listData=[
{
"title":"五资妈ki 那鲁托--漩涡鸣人",
"author":"卡诶本新诺酒煮---影分身之术",
"imageUrl":"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1578674333725&di=ec3da407df99c6251631c8be300cd479&imgtype=jpg&src=http://img3.imgtn.bdimg.com/it/u=2008737948,2044904539&fm=214&gp=0.jpg",
},
{
"title":"萨斯给",
"author":"啊妈忒路斯",
"imageUrl":"http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png",
},
{
"title":"五资妈ki 那鲁托--漩涡鸣人",
"author":"卡诶本新诺酒煮---影分身之术",
"imageUrl":"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1578674333725&di=ec3da407df99c6251631c8be300cd479&imgtype=jpg&src=http://img3.imgtn.bdimg.com/it/u=2008737948,2044904539&fm=214&gp=0.jpg",
},
{
"title":"萨斯给",
"author":"啊妈忒路斯",
"imageUrl":"http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png",
},
{
"title":"五资妈ki 那鲁托--漩涡鸣人",
"author":"卡诶本新诺酒煮---影分身之术",
"imageUrl":"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1578674333725&di=ec3da407df99c6251631c8be300cd479&imgtype=jpg&src=http://img3.imgtn.bdimg.com/it/u=2008737948,2044904539&fm=214&gp=0.jpg",
},
{
"title":"萨斯给",
"author":"啊妈忒路斯",
"imageUrl":"http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png",
},
{
"title":"五资妈ki 那鲁托--漩涡鸣人",
"author":"卡诶本新诺酒煮---影分身之术",
"imageUrl":"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1578674333725&di=ec3da407df99c6251631c8be300cd479&imgtype=jpg&src=http://img3.imgtn.bdimg.com/it/u=2008737948,2044904539&fm=214&gp=0.jpg",
},
{
"title":"萨斯给",
"author":"啊妈忒路斯",
"imageUrl":"http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png",
},
{
"title":"五资妈ki 那鲁托--漩涡鸣人",
"author":"卡诶本新诺酒煮---影分身之术",
"imageUrl":"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1578674333725&di=ec3da407df99c6251631c8be300cd479&imgtype=jpg&src=http://img3.imgtn.bdimg.com/it/u=2008737948,2044904539&fm=214&gp=0.jpg",
},
{
"title":"萨斯给",
"author":"啊妈忒路斯",
"imageUrl":"http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png",
},
{
"title":"五资妈ki 那鲁托--漩涡鸣人",
"author":"卡诶本新诺酒煮---影分身之术",
"imageUrl":"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1578674333725&di=ec3da407df99c6251631c8be300cd479&imgtype=jpg&src=http://img3.imgtn.bdimg.com/it/u=2008737948,2044904539&fm=214&gp=0.jpg",
},
{
"title":"萨斯给",
"author":"啊妈忒路斯",
"imageUrl":"http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png",
},
{
"title":"五资妈ki 那鲁托--漩涡鸣人",
"author":"卡诶本新诺酒煮---影分身之术",
"imageUrl":"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1578674333725&di=ec3da407df99c6251631c8be300cd479&imgtype=jpg&src=http://img3.imgtn.bdimg.com/it/u=2008737948,2044904539&fm=214&gp=0.jpg",
},
{
"title":"萨斯给",
"author":"啊妈忒路斯",
"imageUrl":"http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png",
},
{
"title":"五资妈ki 那鲁托--漩涡鸣人",
"author":"卡诶本新诺酒煮---影分身之术",
"imageUrl":"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1578674333725&di=ec3da407df99c6251631c8be300cd479&imgtype=jpg&src=http://img3.imgtn.bdimg.com/it/u=2008737948,2044904539&fm=214&gp=0.jpg",
},
{
"title":"萨斯给",
"author":"啊妈忒路斯",
"imageUrl":"http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png",
},
{
"title":"五资妈ki 那鲁托--漩涡鸣人",
"author":"卡诶本新诺酒煮---影分身之术",
"imageUrl":"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1578674333725&di=ec3da407df99c6251631c8be300cd479&imgtype=jpg&src=http://img3.imgtn.bdimg.com/it/u=2008737948,2044904539&fm=214&gp=0.jpg",
},
{
"title":"萨斯给",
"author":"啊妈忒路斯",
"imageUrl":"http://n.sinaimg.cn/sinacn/w813h463/20180130/46b9-fyrcsrv7304762.png",
},
];
接下来我们进行数据转换并且展示到ListView
中。
import 'listData.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'App',
home: Scaffold(
appBar: AppBar(
title: Text('ListView进行Json文件解析'),
),
body: NetListViewTest(),
),
);
}
}
class NetListViewTest extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
children: _getData(),
);
}
List<Widget> _getData() {
var tempList = listData.map((value) {
return ListTile(
leading: Image.network(value['imageUrl']),
subtitle: Text('主要技能:' value['author']),
title: Text('忍者介绍:' value['title']),
);
});
//.map方法其实就是迭代,然后存放在一个对象中
print('-------$tempList');//(ListTile, ListTile, ListTile, ListTile, ListTile, ..., ListTile, ListTile)
print('tempList的对象为:' tempList.runtimeType.toString());//MappedListIterable<dynamic, ListTile>
List<Widget> list = tempList.toList();
print('========$list');//[ListTile, ListTile,..., ListTile, ListTile]
return tempList.toList();
}
}
效果展示如下:
初试ListView.builder
在使用ListView.builder
时,我们需要注意,我们需要将这个两个参数获取到。itemCount
与itemBuilder
itemCount
:表示item个数itemBuilder
:进行数据装填或者数据展示。其方法带有返回值为Widget
先来个小尝试吧!
我们先进行数据的组装,我在构造参数中进行数据的装填,使其每次创建进行20条数据的填充。
代码语言:javascript复制 List<Widget> list = new List<Widget>();
ListViewBuilder() {
for (int i = 0; i < 20; i ) {
this.list.add(ListTile(
title: Text(
'这是第$i标题',
),
));
}
}
进行数据的展示。完整代码如下:
代码语言:javascript复制void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'App',
home: Scaffold(
appBar: AppBar(
title: Text('ListView.builder初试'),
),
body: ListViewBuilder(),
),
);
}
}
class ListViewBuilder extends StatelessWidget {
List<Widget> list = new List<Widget>();
ListViewBuilder() {
for (int i = 0; i < 20; i ) {
this.list.add(ListTile(
title: Text(
'这是第$i标题',
),
));
}
}
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: list.length,
itemBuilder: (context, index) {
return list[index];
},
);
}
}
ListView.builder
Demo
代码语言:javascript复制void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'App',
home: Scaffold(
appBar: AppBar(
title: Text('ListView.builder Demo'),
),
body: NetListViewBuidler(),
),
);
}
}
class NetListViewBuidler extends StatelessWidget{
Widget _getListData(context,index){
return ListTile(
leading: Image.network(listData[index]['imageUrl']),
subtitle: Text('主要技能:' listData[index]['author']),
title: Text('忍者介绍:' listData[index]['title']),
);
}
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount:listData.length,
itemBuilder:_getListData,
);
}
}
看到此处的_getListData
,如果有点懵逼的话,则建议你好好看一下Dart的函数。把方法当做参数的方法
至此关于LstView
的学习完毕。不足之处,请大家指导。