⭐️ 개발/플러터
[프로젝트] 전자액자 (3) PageController 사용
짱구러버
2022. 11. 5. 20:39
728x90
들어가기 앞서...
이번 게시글에는 PageVIew() 에서 PageController 를 사용해 페이지를 1초마다 한장씩 넘어가게끔 진행을 할 것이다.
주의 깊게 봐야하는 점...
웹뷰를 썼을때는 onWebViewCreated 함수에서 controller 를 받을 수 있었는데, PageView 같은 경우에는 우리가 알아서 만들어 집어넣어줘야한다.
본문으로...
- State클래스에 PageController 를 선언해주자!
class _HomeScreenState extends State<HomeScreen> {
Timer? timer;
PageController controller = PageController(
// 초기에 몇번째 페이지를 실행할지
initialPage: 0,
);
}
...
- PageController 를 선언해주고 PafeView() 에 controller를 넣어주자!
...
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
return Scaffold(
body: PageView(
// 추가!
controller: controller,
children: [2, 3, 4].map(
(e) => Image.asset('asset/img/img$e.HEIC', fit: BoxFit.cover)
).toList(),
),
);
}
}
PageView가 생성이 되는 순간 controller 가 PageView 에 붙는다.
그리고 controller 를 조정을 할 수 있다!
page 를 쓰려고 하니깐 double? 가 타입으로 나오게 되는 것을 볼 수 있다.
? controller 가 생성만 되고 PageView 에 자동으로 붙지 않았을 경우 페이지를 찾을 수 없으니 null 이될 수도 있다. 그래서 ? 가 들어가는것이다.
그리고 double 인 이유는 페이지가 중간일 경우 소수점으로 나오게 되는데, 그 소수점 떄문에 double 이라는 타입이 되는 것이다!
하지만 우리는 currentPage 는 null 이 안오는 게 확실하고, 양수형으로만 받길 원하니깐 밑에 코드 처럼 작성을 해주자
int currentPage = controller.page!.toInt();
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();
// 다음 페이지는 현재페이지 + 1
int nextPage = currentPage + 1;
// 다음 페이지가 현재 내가 등록해놓은 사진의 배열의 인덳스 보다 많다면? 다음페이지를 0 으로!
if (nextPage > 2) {
nextPage = 0;
}
// controller 의 animateToPage 로 페이지 이동시켜준다.
controller.animateToPage(
nextPage, duration: Duration(milliseconds: 400), curve: Curves.ease);
});
}
페이지를 바꿀수 있는 기능 이다.
controller.animateToPage( page: 어떤 페이지로 이동 시킬것인지, duration 이동하는 속도, curve : 애니메이션 지정)
- 이제는 Controller 도 disPose 해주자!
모든 Controller 는 메모리 누수가 일어 날 수 있기에 종료를 시켜줘야한다!
방금 만든 Controller 도 State 가 삭제 될때 Controller 도 종료되게끔, disPose 해주자!
...
@override
void dispose() {
// 추가!
controller.dispose();
if (timer != null) {
timer!.cancel();
}
super.dispose();
}
...
꿀팁💡 상단 시간과 위젯 이미지들 색상 바꾸는 방법 💡
이미지의 배경화면 색상이 흰색이라면 상단 부분의 컬러가 white 이기 떄문에 안보인다. 그래서 바꿔주자!
...
import 'package:flutter/services.dart';
...
SystemChrome.setSystemUIOverlayStryle(SystemUiOverlayStyle.light); // 흰색
SystemChrome.setSystemUIOverlayStryle(SystemUiOverlayStyle.dark); // 검은색
완성 코드 )
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
State<HomeScreen> createState() => _HomeScreenState();
}
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 > 2) {
nextPage = 0;
}
controller.animateToPage(
nextPage, duration: Duration(milliseconds: 400), curve: Curves.ease);
});
}
@override
void dispose() {
controller.dispose();
if (timer != null) {
timer!.cancel();
}
super.dispose();
}
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
return Scaffold(
body: PageView(
controller: controller,
children: [2, 3, 4].map(
(e) => Image.asset('asset/img/img$e.HEIC', fit: BoxFit.cover)
).toList(),
),
);
}
}
끝으로...
- pageController 를 따로 생성해 pageView 가 생성될때 controller 를 넣어 줄 수 있다!
- 현재 페이지, 다음 페이지를 변수 선언해서 controller.animateToPage() 로 페이지를 이동 시킬수 있다!
- 메모리 누수 방지를 위한 Controller 를 disPose() 할 수 있다.

728x90