내가 보려고 쓰는 Flutter Widget 일기
출처 : https://api.flutter.dev/flutter/widgets/ListView-class.html
오늘 배워본 위젯은 ListView.
공식 페이지 설명에서는, 스크롤이 가능한 위젯으로 가장 많이 사용된다고 한다. 스크롤되는 방향으로 자식 요소들이 나열되어서 화면에 나타나게 해준다.
공식 페이지에서 제공하는 코드를 가져와 자식 요소를 몇개 더 추가해서 돌려보았다. 자식요소만 추가한 거라 기능은 동일하다. 아래에서 return Scaffold 부분부터 ListView가 들어있다.
코드 예시로 알아보자
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
//요기부터 주의해서 봐주면 된다.
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
padding: const EdgeInsets.symmetric(vertical: 30),
children: <Widget>[ //자식 위젯들이 여러 개 나열되어 있다.
Container(
height: 50,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 50,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
color: Colors.amber[400],
child: const Center(child: Text('Entry C')),
),
Container(
height: 50,
color: Colors.amber[300],
child: const Center(child: Text('Entry D')),
),
Container(
height: 50,
color: Colors.amber[200],
child: const Center(child: Text('Entry E')),
),
Container(
height: 50,
color: Colors.amber[100],
child: const Center(child: Text('Entry F')),
),
],
),
);
}
}
그냥 색깔 다르고 똑같은 네모가 여러개인데, 반복되는 코드가 많아 코드가 너무너무 길다. 생긴걸 똑같이 표현할건데 코드를 좀 더 간단하게 할 순 없을까? 설명을 더 내려보니 ListView.builder 와 ListView.separated가 있네
ListView.builder를 사용할 때에는, itemCount와 itemBuilder를 이용해서 생성한다. itemCount는 스크롤의 최대 길이값, 즉 리스트에 나타낼 요소의 최대값으로 지정한다.
이 itemCount값보다 index값이 작은 동안 itemBuilder에 지정된 콜백 함수가 실행된다. index값은 보통 그렇듯 0번부터 시작한다. (근데 또 궁금해서 화면에 찍어봤다. 0~5까지 잘 나왔다.)
아래 코드에서는 itemCount가 entries.length로 들어갔기 때문에 6이다. 0번부터 5번까지 -> 6번 실행된다.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final List<String> entries = <String>['A', 'B', 'C', 'D', 'E', 'F'];
final List<int> colorCodes = <int>[600, 500, 400, 300, 200, 100];
Widget build(BuildContext context) {
return Scaffold(
//요기부터 보면 훨씬 간단해진 걸 알 수 있다.
body: ListView.builder(
padding: const EdgeInsets.symmetric(vertical:30),
itemCount: entries.length,
itemBuilder: (BuildContext context, int index) {
//index가 궁금하면 요기다가 넣고 화면에 찍어보세요
//print("itembuilder: ${index}");
return Container(
height: 50,
color: Colors.amber[colorCodes[index]],
child: Center(child: Text('Entry ${entries[index]}')),
);
}
)
);
}
}
화면에 나오는 건 똑같은데, Scaffold 아래의 코드가 훨씬 짧아진 걸 알 수 있다.
이제 ListView.separated는 어떤지 보자.
build(BuildContext context) {
return Scaffold(
body: ListView.separated(
padding: const EdgeInsets.symmetric(vertical: 30),
itemCount: entries.length,
separatorBuilder: (BuildContext context, int index) =>
const Divider(thickness: 3),
itemBuilder: (BuildContext context, int index) {
return Container(
height: 50,
color: Colors.amber[colorCodes[index]],
child: Center(child: Text('Entry ${entries[index]}')),
);
})
);
}
Widget
Listview.builder 를 ListView.separated로 변경하고 separatorBuilder 속성 하나를 추가한게 끝이다. Divider()안에 thickness는 구분선이 잘 안보여서 추가해봤다. (없어도 된다)
화면에 띄워보면 아래와 같다.
오늘의 일기는 여기까지!