나는 이렇게 학습한다/App

flutter _ PageView 와 PageController, Timer 사용방법

daco2020 2023. 1. 1. 20:08
반응형

main

import 'package:flutter/material.dart';
import 'package:image_carousel/screen/home_screen.dart';

void main() {
  runApp(
    MaterialApp(
      home: HomeScreen(),
    ),
  );
}

설명은 생략

 

 

 

 

 

 

HomeScreen StatefulWidget

class _HomeScreenState extends State<HomeScreen> {
  Timer? timer;
  PageController controller = PageController(
    initialPage: 0,
  );

State에 Timer 와 PageController 선언

initialPage는 인덱스니까 당연히 0

 

 

 

 

 

@override
void initState() {
  super.initState();
  
  timer = Timer.periodic(Duration(seconds: 2), (timer) { // 2초 짜리 타이머가 요기로 들어옴
    int currentPage = controller.page!.toInt(); // page는 원래 double(소수점)이다. 중간이 있기 때문에
    int nextPage = currentPage + 1;

    if(nextPage > 4){
      nextPage = 0;
    }

    controller.animateToPage(nextPage, duration: Duration(milliseconds: 400), curve: Curves.ease); // 페이지 넘김 애니메이션
  });
}

initSate 에는 타이머 객체를 만들고 현재 페이지와 다음 페이지에 대한 값을 할당한다.

다음 페이지가 4를 초과하면 (이미지가 5개만 있음) 다음 페이지를 0으로 할당한다.

controller.animateToPage는 페이지를 넘길 때 애니메이션을 줄 수 있음

 

 

 

 

@override
void dispose() {
  controller.dispose(); // controller는 dispose 해주어야 메모리 누수를 막을 수 있다.
  if(timer != null){
    timer!.cancel();
  }
  super.dispose();
}

위젯이 죽을 때에는 controller와 timer를 없애줘야 메모리 누수를 막을 수 있음

 

 

 

 

  @override
  Widget build(BuildContext context) {
    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark); // ui와 관련없는 상태바 요소의 색상을 변경

    return Scaffold(
      body: PageView( // 페이지를 만들 수 있음
        controller: controller,
        children: [1, 2, 3, 4, 5]
            .map((e) => // map을 이용하면 파일명을 동적으로 전달할 수 있음
                Image.asset('asset/img/image_$e.jpeg', fit: BoxFit.cover))
            .toList(),
      ),
    );
  }
}

SystemChrome.setSystemUIOverlayStyle 는 시스템 ui의 스타일을 바꿔줄 수 있음(배터리, 시간, 와이파이 같은 요소들)

PageView 에 controller 붙이고 map을 이용해 Image.asset에 파일명을 동적으로 전달

 

 

 

 

 

결과 화면

 

 

 

 

 

 

전체 코드

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

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: 2), (timer) { // 1초 짜리 타이머가 요기로 들어옴
      int currentPage = controller.page!.toInt(); // page는 원래 double(소수점)이다. 중간이 있기 때문에
      int nextPage = currentPage + 1;

      if(nextPage > 4){
        nextPage = 0;
      }

      controller.animateToPage(nextPage, duration: Duration(milliseconds: 400), curve: Curves.ease); // 페이지 넘김 애니메이션
    });
  }

  @override
  void dispose() {
    controller.dispose(); // controller는 dispose 해주어야 메모리 누수를 막을 수 있다.
    if(timer != null){
      timer!.cancel();
    }
    super.dispose();
  }
  
  @override
  Widget build(BuildContext context) {
    SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark); // ui와 관련없는 상태바 요소의 색상을 변경

    return Scaffold(
      body: PageView( // 페이지를 만들 수 있음
        controller: controller,
        children: [1, 2, 3, 4, 5]
            .map((e) => // map을 이용하면 파일명을 동적으로 전달할 수 있음
                Image.asset('asset/img/image_$e.jpeg', fit: BoxFit.cover))
            .toList(),
      ),
    );
  }
}

 

 

 

반응형