移动端数据量比较大时,我们都是通过列表来进行展示的,比如商品数据、聊天列表、通信录、朋友圈等。
在Android中,我们可以使用ListView或RecyclerView来实现,在iOS中,我们可以通过UITableView来实现。
在Flutter中,我们也有对应的列表Widget,就是ListView。
一、ListView
1.1、ListView的基本使用
ListView可以沿一个方向(垂直或水平方向,默认是垂直方向)来排列其所有子Widget。
一种最简单的使用方式是直接将所有需要排列的子Widget放在ListView的children属性中即可。
我们直接使用ListView进行演练:
class MyHomeBody extends StatelessWidget {
final TextStyle textStyle = TextStyle(fontSize: 20, color: Colors.redAccent);
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("人的一切痛苦,本质上都是对自己无能的愤怒。", style: textStyle),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("人活在世界上,不可以有偏差;而且多少要费点劲儿,才能把自己保持到理性的轨道上。", style: textStyle),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text("我活在世上,无非想要明白些道理,遇见些有趣的事。", style: textStyle),
)
],
);
}
}
效果图如下:
1.2、ListTitle的使用
在开发中,我们经常见到一种列表,有一个图标或图片(Icon),有一个标题(Title),有一个子标题(Subtitle),还有尾部一个图标(Icon)。
我们使用ListTitle来实现:
class MyHomeBody extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
ListTile(
leading: Icon(Icons.people, size: 36,),
title: Text("联系人"),
subtitle: Text("联系人信息"),
trailing: Icon(Icons.arrow_forward_ios),
),
ListTile(
leading: Icon(Icons.email, size: 36,),
title: Text("邮箱"),
subtitle: Text("邮箱地址信息"),
trailing: Icon(Icons.arrow_forward_ios),
),
ListTile(
leading: Icon(Icons.message, size: 36,),
title: Text("消息"),
subtitle: Text("消息详情信息"),
trailing: Icon(Icons.arrow_forward_ios),
),
ListTile(
leading: Icon(Icons.map, size: 36,),
title: Text("地址"),
subtitle: Text("地址详情信息"),
trailing: Icon(Icons.arrow_forward_ios),
)
],
);
}
}
效果图如下:
1.3、垂直方向滚动
我们可以通过设置 scrollDirection 参数来控制视图的滚动方向。
我们通过下面的代码实现一个水平滚动的内容:
class MyHomeBody extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
scrollDirection: Axis.horizontal,
itemExtent: 200,
children: <Widget>[
Container(color: Colors.red, width: 200),
Container(color: Colors.green, width: 200),
Container(color: Colors.blue, width: 200),
Container(color: Colors.purple, width: 200),
Container(color: Colors.orange, width: 200),
],
);
}
}
需要注意的是,我们给Container设置width,否则它没有宽度,不能正常显示;我们给ListView设置一个itemExtent,该属性会设置滚动方向上每个item所占据的宽度。
2.1、ListView.build
通过构造函数中的children传入所有的子Widget有一个问题:默认会创建出所有的子Widget。
但是对于用户来说,一次性构建出所有的Widget并不会有什么差异,但是对于我们的程序来说会产生性能问题,而且会增加首屏的渲染时间。
我们可以ListView.build来构建子Widget,提供性能。
2.1.1、ListView.build基本使用
ListView.build适用于子Widget比较多的场景,该构造函数将创建子Widget交给了一个抽象的方法,交给ListView进行管理,ListView会在真正需要的时候去创建子Widget,而不是一开始就全部初始化好。
ListView.build方法有两个重要参数:
-
itemBuilder:列表项创建的方法。当列表滚动到对应位置的时候,ListView会自动调用该方法来创建对应的子Widget。类型是IndexedWidgetBuilder,是一个函数类型。
-
itemCount:表示列表项的数量,如果为空,则表示ListView为无限列表。
class MyHomeBody extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: 100,
itemExtent: 80,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text("标题$index"), subtitle: Text("详情内容$index"));
}
);
}
}
2.1.2、ListView.build动态数据
之前搞了一个test.json文件,里面的数据如下:
{
"status": "0000",
"message": "success",
"data": {
"title": {
"id": "001",
"name" : "蔬菜"
},
"content": [
{
"id": "001",
"value":"白菜"
},
{
"id": "002",
"value":"萝卜"
},
{
"id": "003",
"value":"黄瓜"
},
{
"id": "004",
"value":"西红柿"
},
{
"id": "005",
"value":"茄子"
},
{
"id": "006",
"value":"冬瓜"
}
]
}
}
又写了一个model:
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
import 'dart:convert';
class ContentModel{
String status;
String message;
Data data;
ContentModel.fromMap(Map<String,dynamic> json){
this.status = json["status"];
this.message = json["message"];
var data = json["data"];
this.data = Data.fromMap(data["title"],data['content']);
}
}
Future<List<contentItem>> getContents() async{
var jsonString = await rootBundle.loadString('json/test.json');
final jsonResult = json.decode(jsonString);
Map map = new Map<String, dynamic>.from(jsonResult);
var data = jsonResult["data"];
List<contentItem> contents = new List();
for(Map<String,dynamic>map in data["content"]){
contents.add(contentItem.fromMap(map));
}
return contents;
}
class Data{
Datatitle title;
List <contentItem> contents;
Data.fromMap(Map<String,dynamic> title,List<dynamic> content){
this.title = Datatitle.fromMap(title);
var contents = content;
this.contents = content.map((item) {
return contentItem.fromMap(item);
}).toList();
}
}
class Datatitle{
String id;
String name;
Datatitle.fromMap(Map<String,dynamic>title){
this.id = title['id'];
this.name = title['name'];
}
}
class contentItem{
String id;
String value;
contentItem.fromMap(Map<String,dynamic>title){
this.id = title['id'];
this.value = title['value'];
}
}
现在我们用json数据来展示一个列表。
现在我们进行一个思考
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)