
开篇寄语
伯衡君发现总结了有关flutter编程语言以制作全平台的App,通过前一篇梳理Widgets组件和Layouts布局内容,感到思路清晰了不少,这一篇文章继续进行梳理,有关Lists的内容,这个简单来说就是各种行的不同形式,伯衡君希望进行梳理后,有一个整体的认知,让我们开始吧。
前情提要
- 《如何在Mac M1芯片电脑上安装Flutter并建立自己第一个全系统应用》
- 《如何在Windows电脑上安装Flutter并建立自己第一个全系统应用》
- 《Flutter制作自己的第一个全平台APP学习之Widgets篇》
- 《Flutter制作自己的第一个全平台APP学习之Layouts篇》
内容详情
以下内容大多是更改lib下的main.dart文件内容,删掉里面的内容,复制粘贴代码,开启调试就可以出现了。
ListTile
- 单个固定高度的行,通常包含一些文本以及前导或尾部图标,试举一例如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root
// of your application
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Insert Image Demo'),
),
body: Column(children: <Widget>[
Card(child: ListTile(title: Text('Hello World!'))),
Card(child: ListTile(title: Text('Hello World!!'))),
Card(child: ListTile(title: Text('Hello World!!!'))),
]),
),
);
}
}
生成效果如下图所示:

ListView.builder
- 简单来说就是批量构建行的函数,试举例如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
List<String> litems = [
"1",
"2",
"Third",
"4",
"a",
"b",
"c",
"d",
"22",
"111"
];
// This widget is the root
// of your application
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Insert Image Demo'),
),
body: new ListView.builder(
itemCount: 10,
itemBuilder: (BuildContext ctxt, int index) {
return new Card(
child: Text(litems[index]));
}),
),
);
}
}
生成效果如下图所示:

GridList
- 想必大家对于相册并不陌生,这个类就相当于相册的展现形式,试举例如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
List<String> litems = [
"1",
"2",
"Third",
"4",
"a",
"b",
"c",
"d",
"22",
"111"
];
// This widget is the root
// of your application
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Insert Image Demo'),
),
body: GridView.count(
// Create a grid with 2 columns. If you change the scrollDirection to
// horizontal, this produces 2 rows.
crossAxisCount: 2,
// Generate 100 widgets that display their index in the List.
children: List.generate(100, (index) {
return Center(
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey, width: 3.0),
),
padding: const EdgeInsets.all(16.0),
child: Text(
'Item $index',
style: Theme.of(context).textTheme.headline5,
),
),
);
}),
),
),
);
}
}
生成效果如下图所示:

ExpansionTile
- 这个是点击后展开隐藏内容,相当于Web中点击后出现列表<li></li>这样,试举例如下,首先是在main.dart内输入以下代码:
import 'package:flutter/material.dart';
import 'home.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Expansion View',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Home(),
);
}
}
接着在main.dart文件的文件夹下新建home.dart文件,输入以下代码:
import 'package:flutter/material.dart';
import 'expansionTile.dart';
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Flutter Expansion View',
),
centerTitle: true,
elevation: 0.0,
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 30.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) =>
Expansiontile()));
},
child: Text('ExpansionTile'),
),
),
],
),
],
),
),
);
}
}
接着还是在文件夹下,新建一个名为expantionTile.dart文件,输入以下代码:
import 'package:flutter/material.dart';
class Expansiontile extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Expansion Tile'),
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 30.0),
child: Column(
children: <Widget>[
SizedBox(height: 20.0),
ExpansionTile(
title: Text(
"Title",
style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),
),
children: <Widget>[
ExpansionTile(
title: Text(
'Sub title',
),
children: <Widget>[
ListTile(
title: Text('data'),
)
],
),
ListTile(
title: Text('data'),
)
],
),
],
),
),
);
}
}
生成效果如下图所示:

Swipe to Dismiss
- 左右滑动,删除掉该行,这种方式很常见以在构建App,试举例如下:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
// ignore: must_be_immutable
class MyApp extends StatelessWidget {
List<String> items = [
"1",
"2",
"Third",
"4",
"a",
"b",
"c",
"d",
"22",
"111"
];
// This widget is the root
// of your application
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Insert Image Demo'),
),
body: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return Dismissible(
// Each Dismissible must contain a Key. Keys allow Flutter to
// uniquely identify widgets.
key: Key(item),
// Provide a function that tells the app
// what to do after an item has been swiped away.
onDismissed: (direction) {
// Remove the item from the data source.
items.removeAt(index);
// Then show a snackbar.
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('$item dismissed')));
},
// Show a red background as the item is swiped away.
background: Container(color: Colors.red),
child: ListTile(title: Text('$item')),
);
}),
));
}
}
生成效果如下图所示:

DataTable
- 这个是新建一个交互式或者非交互式的表格,展现更多的信息,试举例如下:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
/// This is the main application widget.
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const MyStatelessWidget(),
),
);
}
}
/// This is the stateless widget that the main application instantiates.
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return DataTable(
columns: const <DataColumn>[
DataColumn(
label: Text(
'Name',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Age',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Role',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Ranking',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
],
rows: const <DataRow>[
DataRow(
cells: <DataCell>[
DataCell(Text('MM')),
DataCell(Text('20')),
DataCell(Text('girl')),
DataCell(Text('98')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('MM')),
DataCell(Text('20')),
DataCell(Text('girl')),
DataCell(Text('98')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('MM')),
DataCell(Text('20')),
DataCell(Text('girl')),
DataCell(Text('98')),
],
),
DataRow(
cells: <DataCell>[
DataCell(Text('MM')),
DataCell(Text('20')),
DataCell(Text('girl')),
DataCell(Text('98')),
],
),
],
);
}
}
生成效果如下图所示:

ReorderableListView
- 用户可以进行自定义排序的一个类,在App中很常见,试举例如下:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
// Remove the debug banner
debugShowCheckedModeBanner: false,
title: 'Kindacode.com',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// Generate dummy data for the list view
List<String> _products =
List.generate(100, (index) => "Product ${index.toString()}");
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Reorder Demo'),
),
body: ReorderableListView.builder(
itemCount: _products.length,
itemBuilder: (context, index) {
final String productName = _products[index];
return Card(
key: ValueKey(productName),
color: Colors.amberAccent,
elevation: 1,
margin: const EdgeInsets.all(10),
child: ListTile(
contentPadding: EdgeInsets.all(30),
title: Text(
productName,
style: TextStyle(fontSize: 18),
),
onTap: () {/* Do something else */},
),
);
},
// The reorder function
onReorder: (oldIndex, newIndex) {
setState(() {
if (newIndex > oldIndex) {
newIndex = newIndex - 1;
}
final element = _products.removeAt(oldIndex);
_products.insert(newIndex, element);
});
}),
);
}
}
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
// Remove the debug banner
debugShowCheckedModeBanner: false,
title: 'Kindacode.com',
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// Generate dummy data for the list view
List<String> _products =
List.generate(100, (index) => "Product ${index.toString()}");
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Reorder Demo'),
),
body: ReorderableListView.builder(
itemCount: _products.length,
itemBuilder: (context, index) {
final String productName = _products[index];
return Card(
key: ValueKey(productName),
color: Colors.amberAccent,
elevation: 1,
margin: const EdgeInsets.all(10),
child: ListTile(
contentPadding: EdgeInsets.all(30),
title: Text(
productName,
style: TextStyle(fontSize: 18),
),
onTap: () {/* Do something else */},
),
);
},
// The reorder function
onReorder: (oldIndex, newIndex) {
setState(() {
if (newIndex > oldIndex) {
newIndex = newIndex - 1;
}
final element = _products.removeAt(oldIndex);
_products.insert(newIndex, element);
});
}),
);
}
}
生成效果如下图所示:

Slidable list tile
- 这个类似于dismiss,左右滑动,但不是消除,而是出现选项,比如常用的邮箱App,标记已读或者删除等活动行为,就可以用此方法,试举一例:
首先是在pubspec.yaml这个文件添加支持的库,如下所示:
dependencies:
flutter:
sdk: flutter
flutter_slidable: ^0.6.0
之后就可以在main.dart文件中调用了,代码如下:
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
final List<String> items =
new List<String>.generate(10, (i) => "item ${i + 1}");
return Scaffold(
appBar: AppBar(
title: Text("Flutter Slideable Example"),
),
body: ListView.separated(
separatorBuilder: (context, index) => Divider(
color: Colors.black,
),
itemCount: items.length,
itemBuilder: (context, int index) {
return Slidable(
actions: <Widget>[
IconSlideAction(
icon: Icons.more,
caption: 'MORE',
color: Colors.blue,
onTap: () {
print("More ${items[index]} is Clicked");
}),
],
secondaryActions: <Widget>[
IconSlideAction(
icon: Icons.clear,
color: Colors.red,
caption: 'Cancel',
onTap: () {
print("Cancel ${items[index]} is Clicked");
})
],
child: ListTile(
leading: Icon(Icons.message),
title: Text("${items[index]}"),
subtitle: Text("Slide left or right"),
trailing: Icon(Icons.arrow_back),
),
actionPane: SlidableDrawerActionPane(),
);
}),
);
}
}
生成效果如下图所示:

- 我的微信
- 微信扫一扫加好友
-
- 我的微信公众号
- 扫描关注公众号
-





