[주요기술]
Children
으로 받음map
하면 끝에 무조건 toList()
해줘야함map
하면 이터러블이 return
이 되는데 childeren
에는 우리가 List
를 받기 땜에futuer.delayed
와 비슷
타이머로는 periodic
을 사용해서 지속적으로 무언가를 실행할 수 있는 방법사용
Dart에서 기본 제공해주는것이 아니라 다트에이싱크 패키지를 불러와야한다.
이유는?
- initState가 이미 불려있기 때문
- hot reload를 했을 때는 build만 다시 실행이 되기 때문에 state도 다시 생성이 되지 않는다.
- 그렇기 때문에 initState에 변경된 사항을 반영하여면 디바이스 재시작을 해야한다.
dispose
을 사용해서 위젯이 사라질 때(해당 Screen이 죽을때) timer 또한 죽어야된다는 명령을 해줌dispose
- state가 죽을 때 실행
- state의 생명주기의 마지막이 dispose임
- 무조건
super.dispose();
윗 줄에 입력
이제 화면에 적용해보자
페이지뷰를 변경할 수 있는(컨트롤 할 수 있는) 컨트롤러를 집어넣어서 그 컨트롤러로 initState안에있는 timer안에서 1초 마다 조정
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class TestScreen extends StatefulWidget {
const TestScreen({Key? key}) : super(key: key);
@override
_TestScreenState createState() => _TestScreenState();
}
class _TestScreenState extends State<TestScreen> {
Timer? timer;
// 1. 페이지뷰 컨트롤러를 넣으려면 페이지뷰 컨트롤러를 생성을 해야함
// 페이지 컨트롤러를 만들면 initialPage(초기화할 페이지) 값을 넣어줄 수 있음 - 맨처음 실행 했을 때 우리가 몇번째 페이지를 실행할 건지
PageController controller = PageController(
initialPage: 0,
);
@override
void initState() {
super.initState();
timer = Timer.periodic(const Duration(seconds: 4), (timer) {
// 3. 이 안에서 페이지뷰 컨트롤러 조정
// 현재 페이지를 가져옴
int currentPage = controller.page!.toInt();
// 다음 페이지
int nextPage = currentPage + 1;
// nextPage가 4보다 크면 다음이 없기때문에 다시 0번으로 돌려줘야함
if (nextPage > 4) {
nextPage = 0;
}
// 페이지뷰 컨트롤러를 변경
// animateToPage (페이지가 이동하는게 animation이라 함)
// curve는 애니가 어떤식으로 실행이되는지 지정 Curves치고 .치면 많은 종류가 나옴 (css에서 ani-timing-funtoin 같은거)
controller.animateToPage(
nextPage,
duration: const Duration(milliseconds: 400),
curve: Curves.linear,
);
});
}
@override
void dispose() {
// 이 state가 만약에 사라지는 상태가 되서 dispose가 풀린다면 타이머가 null이 아닐 떄 timer를 취소해줌(controller도 마찬가지)
controller.dispose();
if (timer != null) {
timer!.cancel();
}
super.dispose();
}
@override
Widget build(BuildContext context) {
//앱과 관련없는 상태바 색 변경
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
return Scaffold(
body: PageView(
// 2. 위에서 생성을 했으니 이제 controller에 넣어주면 끝
// 넣어주고 저장을 했을 때 이 페이지뷰가 생성이되는 순간 컨트롤러가 알아서 페이지 뷰에 붙음. 그래서 컨트롤러를 사용해서 페이지뷰를 조정할수가 있음
controller: controller,
children: [1, 2, 3, 4, 5]
.map(
(e) => Image.asset(
'assets/images/swiper/image_$e.jpeg',
fit: BoxFit.cover,
),
)
.toList(),
),
);
}
}