GridView 생성자들.
|
그리드 뷰 모양(로 갯수, 스페이싱등) |
그리드뷰 아이템 |
count |
콜백방식, 갯수지정 |
콜백방식 |
extend |
콜백방식, 넓이지정 |
콜백방식 |
builder |
클래스방식 갯수지정 : SliverGridDelegateWithFixedCrossAxisCount 넓이지정 : SliverGridDelegateWithMaxCrossAxisExtent |
콜백방식 |
custom |
클래스방식 갯수지정 : SliverGridDelegateWithFixedCrossAxisCount 넓이지정 : SliverGridDelegateWithMaxCrossAxisExtent |
클래스 방식 SliverChildBuilderDelegate |
GridView.count
그리드뷰를 사용하데 가장 쉬운 방법은 GridView.count() 생성자를 이용하는 것입니다. crossAxisCount로 한 로우나 컬럼 에 몇개의 아이템을 구성할지를 명시적으로 선언할 수 있기 때문입니다. (로우나 컬럼 이라고 한 건 스크롤 방향 때문인가???)
crossAxisCount를 이용하여 로우 혹은 컬럼의 갯수 지정
https://flutter.dev/docs/cookbook/lists/grid-lists#complete-example 에 있는 100개의 위젯을 보여주는 그리드뷰 예제를 참고 했습니다. (crossAxisSpacing ,mainAxisSpacing 추가, Center위젯대신 Container위젯사용)
전체소스
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(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: GridView.count(
scrollDirection: Axis.horizontal, //스크롤 방향 조절
crossAxisSpacing: 10,
mainAxisSpacing: 10,
crossAxisCount: 6, //로우 혹은 컬럼수 조절 (필수값)
children: List.generate(100, (index) {
return Container(
child:
Text("Item $index", style: Theme.of(context).textTheme.body1),
color: Colors.green,
);
}),
),
);
}
}
GridView.extent
maxCrossAxisExtent 에 한개의 그리드 아이템의 최대넓이 값으로 로우 혹은 컬럼의 갯수 지정
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(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: GridView.extent(
maxCrossAxisExtent: 300.0, //필수값
crossAxisSpacing: 10,
mainAxisSpacing: 10,
children: List.generate(100, (index) {
return Container(
child:
Text("Item $index", style: Theme.of(context).textTheme.body1),
color: Colors.green,
);
}),
));
}
}
GridView.builder
-. 그리드를 만드는 곳은 delegate 클래스가 담당하고, 그리드 아이템을 만드는 것은 builder 콜백이 담당하네요.
-. gridDelegate 인자에 SliverGridDelegateWithMaxCrossAxisExtent혹은 SliverGridDelegateWithFixedCrossAxisCount 를 넘기면 됩니다.
-. 생성자의 인자로 넘겼던 crossAxisSpacing, mainAxisSpacing들이 SliverGridDelegate의 인자로 넘김니다.
itemCount인자는 필수 값이 아니네요. 넘기지 않으면 이 예제에서는 무한으로 올라가네요.
1) SliverGridDelegateWithFixedCrossAxisCount 사용.
crossAxisSpacing, mainAxisSpacing 값이 delegate 인자로 들어 가 있습니다.
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(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: GridView.builder(
itemCount: 100,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
itemBuilder: (BuildContext context, int index) {
return Container(
child:
Text("Item $index", style: Theme.of(context).textTheme.body1),
color: Colors.green,
);
},
));
}
}
2) SliverGridDelegateWithMaxCrossAxisExtent 사용.
위 소스에서 gridDelegate 부분만 바꿔 주면 됩니다.
crossAxisSpacing, mainAxisSpacing 값이 delegate 인자로 들어 가 있습니다.
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 300.0,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
GridView.custom
GridView.builder에서 builder 콜백이 담당하던 그리드 아이템을 만드는 부분을 delegate 클래스가 담당하도록하네요.
childrenDelegate 인자에 SliverChildListDelegate 혹은 SliverChildBuilderDelegate 클래스를 넘기면 됩니다.
1)SliverChildListDelegate 사용
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(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: GridView.custom(
//itemCount: 100,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 300.0,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
),
childrenDelegate: SliverChildListDelegate(List.generate(100, (index) {
return Container(
child:
Text("Item $index", style: Theme.of(context).textTheme.body1),
color: Colors.green,
);
})),
));
}
}
2)SliverChildBuilderDelegate 사용
childrenDelegate 부분만 변경하면 됩니다.
childrenDelegate:
SliverChildBuilderDelegate((BuildContext context, int index) {
return Container(
child:
Text("Item $index", style: Theme.of(context).textTheme.body1),
color: Colors.green,
);
}, childCount: 100),