Flutter 위젯 중 PageView에 대해 알아보자.
출처
PageView
는 페이지 단위로 스크롤 할 수 있는 화면을 그려준다. PageView
에 들어가는 페이지들은 모두 뷰포트(viewport) 사이즈로 화면에 보이게 된다.
뷰포트(ViewPort)란 현재 보고 있는 화면의 영역을 나타낸다. 모바일 뷰포트는 브라우저 창보다 크거나 작고, 상하 좌우로 움직이거나, 더블탭, 줌인, 줌아웃을 통해 뷰포트의 배율을 변경할 수 있다.
Pageiew
는 PageController
를 통하여 컨트롤 된다. 처음 보일 페이지 (initialPage
), 각 페이지가 차지하게 될 뷰포트 사이즈 비율(viewportFraction
) 등을 설정할 수 있다.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return const MaterialApp(
title: 'PageView Example',
home: PageViewExample(),
);
}
}
class PageViewExample extends StatelessWidget {
const PageViewExample({Key? key}) : super(key: key);
Widget build(BuildContext context) {
final PageController controller = PageController(initialPage: 0); //Page 컨트롤을 위한 PageController 선언 시작 페이지 0
return Scaffold(
appBar: AppBar(
title: const Text('PageView example'),
),
body: PageView(
controller: controller, // 페이지 관리를 위한 controller
children: [
Container( // 첫 번째 페이지 구성, 시작페이지
color: Colors.yellow,
child: const Center(
child: Text('First Page'),
),
),
Container( // 두 번째 페이지 구성
color: Colors.green,
child: const Center(
child: Text('Second Page'),
),
),
Container( // 세 번째 페이지 구성
color: Colors.blue,
child: const Center(
child: Text('Third Page'),
),),
],
)
,
);
}
}
PageView
의 children
에 존재하는 3개의 Container
가 각각의 페이지를 구성한다.
페이지를 컨트롤 할 PageController
(예시에 존재하는 controller 변수)를 선언하고, PageView
의 controller
로 할당했다. controller
의 initialPage
를 0으로 설정하여 첫번째 페이지인 노란색 페이지가 제일 먼저 사용자에게 보여진다. 이후 좌우 드래그를 통해 페이지를 넘길 수 있다.
PageView.builder
생성자는 사용자에게 보이고 있는 페이지에 대해서만 builder
를 호출하므로 children
의 개수가 아주 많거나 무한할 경우 유용하게 사용할 수 있다. itemcount
를 통해 children
개수를 설정할 수 있는데 아래 예시처럼 null
로 설정할 경우 개수가 무한대가 된다.
//PageView.builder 사용법
PageView.builder(
controller: _controller,
itemBuilder: (context, index){
return Container(
child: Center(
child: Text(index.toString()),
),
);
},
itemCount: null //null로 설정 시 children 개수 무한대.
)
PageView
를 사용자 의도대로 커스텀할 수 있다. 기본 생성자는 children
을 통해 위젯 리스트를 받아서 childrenDelegate
에 할당시키는 반면, PageView.custom
생성자의 경우 직접 childrenDelegate
으로 받는다.
// 해당 Property 값들은 상황에 맞게 채울 수 있게 채우지 않았다.
class PageCustom extends StatelessWidget{
Widget build(BuildContext context) {
return PageView.custom(
childrenDelegate: , //children 위젯을 PageView 위젯에게 제공하는 역할
pageSnapping: , // 페이지 단위로 화면이 넘어갈지 여부
clipBehavior: , // content가 범위를 넘어갈 때 해당 content를 자르는 방법
controller: , // PageView 컨트롤을 위한 Controller
dragStartBehavior: , // 사용자의 드래그를 인식
onPageChanged: , // 뷰포트 중앙 화면이 변경될 때마다 호출되는 함수
physics: , // 페이지 뷰가 사용자 입력에 반응하는 방법
restorationId: , //스크롤의 위치 정보를 저장하고 복원하는 역할
reverse: , // children 위젯을 역방향으로 보여줄 것인지 여부
scrollDirection: , // 스크롤 방향 여부
allowImplicitScrolling: , // 각 children 위젯들의 내부 스크롤 부여 여부
)
}
}
Property | Description | Type | Default |
---|---|---|---|
allowImplicitScrolling | 각 children 위젯들에 내부 스크롤 부여 여부 | bool | false |
childrenDelegate | children 위젯을 PageView 위젯에게 제공하는 역할 | SliverChildDelegate | |
clipBehavior | content가 범위를 넘어갈 때 해당 content를 자르는 방법 | Clip | Clip.hardEdge |
controller | PageView를 컨트롤하기 위한 컨트롤러 | PageController | |
dragStartBehavior | 사용자의 드래그를 인식하는 방법 | DragStartBehavior | DragStartBehavior.start |
onPageChanged | 뷰포트 중앙에 위치한 페이지가 변경될 때마다 호출되는 함수 | ValueChanged<int> ? | |
pageSnapping | 페이지 단위로 화면이 넘어갈지 여부 | bool | true |
physics | 페이지 뷰가 사용자 입력에 반응하는 방법 | ScrollPhysics? | |
restorationId | 스크롤의 위치 정보를 저장하고 복원하는 역할 | String? | |
reverse | children 위젯을 역방향으로 보여줄 것인지 여부 | bool | false |
scrollDirection | 스크롤 방향, children 위젯 나열 방향 | Axis | Axis.horizontal |