GridView
建構方法
- GridView.count() 固定欄數或列數
- GridView.extent() 子元素最大寬度或高度
- GridView.builder() 搭配 gridDelegate
GridView.count()
使用count()建構方法,建立Widget。
GridView.count(...)
scrollDirection 滾動的方向
注意!滾動的方法預設是垂直(Axis.vertical)
| 屬性 | 說明 |
|---|---|
| Axis.vertical(預設) | 垂直滾動 |
| Axis.horizontal | 水平滾動 |
scrollDirection: Axis.vertical
crossAxisCount 交叉軸數量
滾動方向(scrollDirection)是垂直(Axis.vertical)。
mainAxis 主軸是 vertical 垂直,crossAxis 交叉軸 就是水平。
mainAxis
|
|
|
|
------------------> crossAxis
|
|
|
|
crossAxis 交叉軸是水平,假設crossAxisCount 為 3 ,會呈現「每列只有三個元素」。
x x x 每列只有三個元素
x x x
x x x
x x x
x x x
x x x

Axis.vertical 間隔 Spacing
mainAxisSpacing 為 Axis.vertical。
mainAxisSpacing 上下的間隔大小。
crossAxisSpacing 左右的間隔大小。
scrollDirection: Axis.horizontal
滾動方向(scrollDirection)是水平(Axis.horizontal)。
mainAxis 主軸是 horizontal 水平,crossAxis 交叉軸 就是垂直。
crossAxis
|
|
|
|
------------------> mainAxis
|
|
|
|
crossAxis 交叉軸是垂直,假設crossAxisCount 為 3 ,就固定只有三「列」。
x x x x x x
x x x x x x
x x x x x x

Axis.horizontal 間隔 Spacing
mainAxisSpacing 為 Axis.horizontal
mainAxisSpacing 左右的間隔大小。
crossAxisSpacing 上下的間隔大小。
程式碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import 'package:flutter/material.dart';
void main() {
runApp(MainPage());
}
class MainPage extends StatefulWidget {
MainPage({Key? key}) : super(key: key);
@override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
ScrollController _controller = ScrollController();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: GridView.count(
// 滾動方向
scrollDirection: Axis.vertical,
// 根據crossAxis 固定行數或列數
crossAxisCount: 3,
// 間隔 大小
mainAxisSpacing: 10,
crossAxisSpacing: 10,
// 產生100個元素
children: List.generate(100, (index) {
return Container(
height: 100,
color: Colors.blue,
alignment: Alignment.center,
child: Text("item $index"),
);
}),
)));
}
}
GridView.extent()
固定「寬度」或「高度」的佈局元件。
scrollDirection:Axis.horizontal
每一個子元素的最大「寬」度。
maxCrossAxisExtent: 100,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import 'package:flutter/material.dart';
void main() {
runApp(MainPage());
}
class MainPage extends StatefulWidget {
MainPage({Key? key}) : super(key: key);
@override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
ScrollController _controller = ScrollController();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: GridView.extent(
scrollDirection: Axis.horizontal,
// 每个item的最大宽度
// 100
maxCrossAxisExtent: 100,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
children: List.generate(10, (index) {
return Container(
height: 100,
color: Colors.blue,
alignment: Alignment.center,
child: Text("item $index"),
);
}),
)));
}
}
scrollDirection:Axis.vertical
每一個元素的最大「高」度。
maxCrossAxisExtent: 100,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import 'package:flutter/material.dart';
void main() {
runApp(MainPage());
}
class MainPage extends StatefulWidget {
MainPage({Key? key}) : super(key: key);
@override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
ScrollController _controller = ScrollController();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: GridView.extent(
scrollDirection: Axis.vertical,
// 每一個元素的最大「高」度。
maxCrossAxisExtent: 100,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
children: List.generate(10, (index) {
return Container(
height: 100,
color: Colors.blue,
alignment: Alignment.center,
child: Text("item $index"),
);
}),
)));
}
}
GridView.builder()
屬於Lazy Loading,只有滑動到可見區域,才會建立子元件,之前已滑過沒在可見區域就會被記憶體回收,釋放記憶體空間。
itemCount 要建立的數量
語法
itemCount: 列數
itemCount: 10
itemBuilder 建立子元件
語法
itemBuilder: (BuildContext context, int index) {
// 建立每一列子元件
}
gridDelegate 佈局組件委托
- SliverGridDelegateWithFixedCrossAxisCount 固定列數或欄數
- SliverGridDelegateWithMaxCrossAxisExtent 固定每個元素的寬度或高度
SliverGridDelegateWithFixedCrossAxisCount
固定列數或欄數
scrollDirection: Axis.vertical
GridView 預設 scrollDirection 滾動的方向是垂直(Axis.vertical)
固定欄數為2欄。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class _MainPageState extends State<MainPage> {
ScrollController _controller = ScrollController();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: GridView.builder(
scrollDirection: Axis.vertical,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 10,
crossAxisSpacing: 10),
itemBuilder: (context, index) {
return Container(
height: 100,
color: Colors.blue,
alignment: Alignment.center,
child: Text("item $index"),
);
},
itemCount: 10)));
}
}
scrollDirection: Axis.horizontal
scrollDirection 滾動的方向是水平(Axis.horizontal)
固定列數為2列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class _MainPageState extends State<MainPage> {
ScrollController _controller = ScrollController();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: GridView.builder(
scrollDirection: Axis.horizontal,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 10,
crossAxisSpacing: 10),
itemBuilder: (context, index) {
return Container(
height: 100,
color: Colors.blue,
alignment: Alignment.center,
child: Text("item $index"),
);
},
itemCount: 10)));
}
}
SliverGridDelegateWithMaxCrossAxisExtent
根據滾動方向scrollDirection,固定每個元素的寬度或高度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import 'package:flutter/material.dart';
void main() {
runApp(MainPage());
}
class MainPage extends StatefulWidget {
MainPage({Key? key}) : super(key: key);
@override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
ScrollController _controller = ScrollController();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: GridView.builder(
scrollDirection: Axis.horizontal,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 100, mainAxisSpacing: 10, crossAxisSpacing: 10),
itemBuilder: (context, index) {
return Container(
height: 100,
color: Colors.blue,
alignment: Alignment.center,
child: Text("item $index"),
);
},
itemCount: 10,
)));
}
}
childAspectRatio 寬高比
根據滾動方向scrollDirection,以下比例會呈現不同形狀。
- childAspectRatio: 1 是正方形
- childAspectRatio: 2 長方形
- childAspectRatio: 0.5 長方形


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import 'package:flutter/material.dart';
void main() {
runApp(MainPage());
}
class MainPage extends StatefulWidget {
MainPage({Key? key}) : super(key: key);
@override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
ScrollController _controller = ScrollController();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: GridView.builder(
scrollDirection: Axis.horizontal,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 100,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 0.5),
itemBuilder: (context, index) {
return Container(
height: 100,
color: Colors.blue,
alignment: Alignment.center,
child: Text("item $index"),
);
},
itemCount: 10,
)));
}
}