플러터에서 PageView라는 위젯을 활용하면 페이지가 수동/자동으로 넘어가게 만들 수 있다.
1. 이미지 5개 PageView로 보이도록 만들기
asset/img/image_1.jpeg
asset/img/image_2.jpeg
asset/img/image_3.jpeg
asset/img/image_4.jpeg
asset/img/image_5.jpeg
다섯 개의 이미지를 페이지뷰로 보여주고자 한다.
PageView 위젯 안에 children으로 저 다섯 개 이미지를 그대로 넣어 줘도 되지만, map 함수를 활용해서 다음과 같이 효율적으로 구현했다. map 함수로 string을 다루는 방법은 다음과 같다.
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
children: [1, 2, 3, 4, 5]
.map(
(e) => Image.asset(
'asset/img/image_$e.jpeg',
),
)
.toList(),
),
);
}
}
이처럼 구현하면 이름이 거의 같고 문자 하나씩만 다른 다섯 개 이미지를 한번에 구현할 수 있다.
이제 수동으로 5개 이미지를 왔다갔다 할 수 있다.
2. 이미지가 화면 안에 가득 차게 만들기
이미지가 화면 사이즈에 맞지 않으면 다음 화면과 같이 나온다.
Image.asset()안에 fit 매개변수를 활용하여 사진 비율을 조정할 수 있다. fit 매개변수에 BoxFit.cover 옵션을 선택해서 화면을 꽉 차게 만들었다. 전체 코드는 다음과 같다.
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
children: [1, 2, 3, 4, 5]
.map(
(e) => Image.asset(
'asset/img/image_$e.jpeg',
fit: BoxFit.cover,
),
)
.toList(),
),
);
}
}
3. 일정한 시간마다 한 번씩 실행되는 timer 만들기
상태관리를 해주기 위해 HomeScreenState 클래스 안에 선언해준다.
initState()는 위젯이 생성될 때 딱 한 번만 호출되는 메서드이다. 이 메서드에서 timer를 만들면 timer가 딱 한 번 생성된다.
Timer? timer;
@override
void initState() {
super.initState();
timer = Timer.periodic(Duration(seconds: 4), (timer) {
//자동으로 페이지가 넘어가게 하는 코드가 작성될 부분
});
}
dispose()메서드는 위젯이 사라질 때 호출되는 메서드이다. 이 메서드에서는 timer를 멈춰주도록 한다. 이렇게 하면 위젯이 없는 동안 timer가 남아있는 일이 없기 때문에 메모리 관리를 효율적으로 할 수 있다.
@override
void dispose() {
if (timer != null) {
timer!.cancel();
}
super.dispose();
}
timer뒤에 느낌표!를 붙이는 이유는 timer가 이미 null이 아님을 플러터에게 알려주기 위함이다. 이렇게 하지 않으면 플러터가 에러를 반환한다.
4. PageController(페이지컨트롤러)를 이용해 페이지 자동으로 넘어가게 만들기
PageController 클래스의 animateToPage 매서드를 이용하여 자동으로 페이지가 넘어가도록 만들 수 있다. 해당 매서드와 매서드를 위한 변수들은 timer 안에 선언하면, timer의 Duration마다 수행된다.
class _HomeScreenState extends State<HomeScreen> {
Timer? timer;
PageController controller = PageController(
initialPage: 0,
);
@override
void initState() {
super.initState();
timer = Timer.periodic(Duration(seconds: 4), (timer) {
int currentPage = controller.page!.toInt();
int nextPage = currentPage + 1;
if (nextPage > 4) {
nextPage = 1;
}
controller.animateToPage(nextPage,
duration: Duration(milliseconds: 400), curve: Curves.linear);
});
}
}
initialPage를 먼저 0으로 선언해주고, 4초마다 controller.animateToPage를 사용하여 400밀리초만에 다음 페이지로 넘어가도록 한다. curve 매개변수는 넘어가는 애니메이션의 속도 변화를 의미한다.
이후, PageView위젯 안에 controller로 선언해준 PageViewController을 넣어주면 잘 작동한다.
@override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: controller,
children: [1, 2, 3, 4, 5]
.map(
(e) => Image.asset(
'asset/img/image_$e.jpeg',
fit: BoxFit.cover,
),
)
.toList(),
),
);
}
}
dispose()메서드에 컨트롤러를 없애주는 코드를 추가해서 state가 사라질 때 controller도 지워지도록 해서 메모리를 최적화한다.
@override
void dispose() {
controller.dispose();
if (timer != null) {
timer!.cancel();
}
super.dispose();
}
'모바일 > Flutter,Dart' 카테고리의 다른 글
[Flutter/플러터] GridView(그리드뷰)로 카드형태의 UI 격자모양으로 배치하기 (1) | 2024.01.02 |
---|---|
[Flutter/플러터] Navigator(네비게이터)로 화면 이동하기 / 화면 이동할 때 변수 저장하기 (0) | 2023.07.19 |
[Flutter, 플러터] 위젯 배치 / 정렬 (mainAxisAlignment, crossAxisAlignment, mainAxisSize, Expanded, Flexible) (0) | 2023.07.16 |
[Flutter/플러터] 화면에 이미지 넣기 / 로딩화면 만들기 (0) | 2023.07.15 |
[Dart/Flutter] Dart언어 배우기 - 함수형 프로그래밍 (0) | 2023.07.06 |