「这是我参与11月更文应战的第4天,活动概况检查:2021最终一次更文应战」
咱们在开发中,经常会需求显现列表,在iOS
中咱们运用UITableView
来完成列表,那么在Flutter
中,对应的部件为ListView
;咱们运用ListView
来开始完成一个简略的列表界面;
ListView的运用
model模型
已然要显现一个列表,那么咱们就需求在列表中显现一个数据模型,这儿咱们创立一个article.dart
文件,在其间创立一个模型:
class Article {
const Article(this.name, this.iconUrl); // 结构函数
final String name;
final String iconUrl;
}
模型的创立办法还有另外一种,如下:
class Article {
const Article({this.name, this.iconUrl}); // 结构函数 可选赋值
final String? name; // ? 表示空安全
final String? iconUrl;
}
那么,这两种创立办法有什么区别呢?
-
const Article(this.name, this.iconUrl);
是一个结构函数,初始化时name
和iconUrl
有必要赋值; -
const Article({this.name, this.iconUrl});
也是一个结构函数,其初始化时name
和iconUrl
可以不进行赋值,可是此刻需求留意有必要满意以下两个条件中的任一个:-
name
和iconUrl
有必要有默认值; -
name
和iconUrl
设置为空安全;
-
List数据源
为了方便,咱们直接在article.dart
文件中创立一个数组,来寄存Article
类作为列表的数据源;
final List<Article> datas = [] // 具体内容没有放出来
此刻,article.dart
文件如下:
ListView
在运用之前,咱们首先需求知道假如创立ListView
,咱们在运用ListView
的时分一般不直接进行结构创立,而是运用其命名结构函数
进行创立;创立代码如下:
ListView.builder(itemBuilder: itemBuilder)
builder
就是在创立ListView
的时分,咱们需求一个烘托;itemBuilder
是一个办法回调;依据其定义
required IndexedWidgetBuilder itemBuilder,
咱们了解到其回来的是IndexedWidgetBuilder
:
typedef IndexedWidgetBuilder = Widget Function(BuildContext context, int index);
此函数回来了一个Widget
,咱们留意到,函数中有两个参数context
和index
,这个时分,依据以往iOS
开发经历,咱们立刻意识到其作用类似于UITableView
中的cellForRow
办法;
咱们依据此函数,创立一个回来Widget
的办法:
Widget _itemForRow(BuildContext context, int index) {
return null
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter 工程'),
),
body: ListView.builder(
itemBuilder: _itemForRow,
itemCount: datas.length,
),
);
}
-
_
表示内部拜访,文件内部! -
_itemForRow
办法回来每一个cell
的视图; -
itemCount
办法传递整个列表中数据个数;
显现文章标题
咱们先简略回来一个Text
部件显现文章标题:
Widget _itemForRow(BuildContext context, int index) {
return Text(datas[index].name);
}
留意,假如name
特点为空安全
的,那么此刻需求进行强制解包:
Widget _itemForRow(BuildContext context, int index) {
return Text(datas[index].name!);
}
运行作用:
显现封面图片
加载图片时,咱们运用Image
部件;
Image.network(’‘)
咱们将_itemForRow
函数代码修正如下:
Widget _itemForRow(BuildContext context, int index) {
return Container(
color: Colors.white,
margin: const EdgeInsets.all(10),
child: Image.network(datas[index].iconUrl),
);
}
Container
是一个常用的小部件,方便咱们进行布局
显现作用:
显现标题和封面
咱们发现Container
部件的child
只能显现一个部件,这样咱们就不能一起显现文章的标题和封面了;
那么,有没有一个部件,它可以寄存多个部件呢?咱们希望在封面的下方能显现出标题,封面和标题竖着排列,这个时分,就有Column
部件可以到达这个作用,并且Column
部件有children
特点是个数组,可以一起寄存多个部件:
Widget _itemForRow(BuildContext context, int index) {
return Container(
color: Colors.white,
margin: const EdgeInsets.all(10),
child: Column(
children: [
Image.network(datas[index].iconUrl),
Container(height: 10,),
Text(
datas[index].name,
style: const TextStyle(
fontSize: 20,
),)
],
),
);
}
Container(height: 10,),
:封面与标题之间间隔10像素的间隔,同样的作用SizedBox
部件或许完成;
作用如下: 完整代码如下:
class ListViewDemo extends StatelessWidget {
// _的内部是指 文件内部!
Widget _itemForRow(BuildContext context, int index) {
return Container(
color: Colors.white,
margin: const EdgeInsets.all(10),
child: Column(
children: [
Image.network(datas[index].iconUrl),
const SizedBox(height: 10,),
Text(
datas[index].name,
style: const TextStyle(
fontWeight: FontWeight.w800,
fontSize: 20,
),)
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey,
appBar: AppBar(
title: const Text('ListView的运用'),
),
body: ListView.builder(
itemBuilder: _itemForRow,
itemCount: datas.length,
),
);
}
}
Flutter小常识
部件的布局只要三种:
- 竖着
- 横着
- 叠着