전자액자 만들기

shin·2022년 10월 4일
0

Flutter

목록 보기
5/12
  • PageView (터치로 좌, 우 스크롤)
  • Timer(특정 기간마다 지정함수 실행)\
  • StatefulWidget
  • Life Cycle

PageView 위젯 사용

  • Scaffold() 위젯 body에 PageView 위젯을 넣고 children을 사용해 이미지 파일들을 넣는다.
  • 화면을 좌, 우로 넘겨본다.
import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView(
        children: [
          Image.asset('asset/img/image_1.jpeg'),
          Image.asset('asset/img/image_2.jpeg'),
          Image.asset('asset/img/image_3.jpeg'),
          Image.asset('asset/img/image_4.jpeg'),
          Image.asset('asset/img/image_5.jpeg'),
        ],
      ),
    );
  }
}

  • 화면 위아래 공백을 채우려면 Image.asset('asset/img/image_1.jpeg')에서fit: BoxFit.cover를 추가해주면 된다. Image.asset('asset/img/image_1.jpeg', fit: BoxFit.cover)
import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView(
        children: [
          Image.asset(
            'asset/img/image_1.jpeg',
            fit: BoxFit.cover,
          ),
          Image.asset(
            'asset/img/image_2.jpeg',
            fit: BoxFit.cover,
          ),
          Image.asset(
            'asset/img/image_3.jpeg',
            fit: BoxFit.cover,
          ),
          Image.asset(
            'asset/img/image_4.jpeg',
            fit: BoxFit.cover,
          ),
          Image.asset(
            'asset/img/image_5.jpeg',
            fit: BoxFit.cover,
          ),
        ],
      ),
    );
  }
}
  • 아래 코드가 숫자 빼고 반복적으로 작성되는 것을 볼 수 있다.
  • map()을 사용해서 좀 더 효율적으로 코드를 변경해볼수 있다.
Image.asset(
            'asset/img/image_1.jpeg',
            fit: BoxFit.cover,
          )
import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  
  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(),
            // map()을 사용해서 코드를 간소화 시킬수 있다.
      ),
    );
  }
}

Timer

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

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  Timer? timer;
  // async 패키지를 불러와야 사용가능하다.

  // initstate()를 만들어 여기서에 Timer를 넣어준다.
  
  void initState() {
    super.initState();

    timer = Timer.periodic(Duration(seconds: 1), (timer) {
      // Future.delay와 같은 구조이다.
      print('Timer');
    });
  }
  // 코드를 실행해보면 콘솔에 아무것도 나오지 않는다.
  // 이유는 initState가 이미 불려있기 때문이다.
  // hot reload를 할 때는 build만 다시 실행되기 때문에 state가 다시 생성되지 않는다.
  // 그래서 hot restart를 해줘야 반영이 된다.
  
  // restart를 하면 콘솔에 1초에 한번씩 Timer가 뜨는걸 볼 수 있다.
  
  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(),
      ),
    );
  }
}

  • Timer는 멈추라고 할 때까지 백그라운드에서 계속 작동하게 된다. 그렇게되면 메모리를 많이 잡아먹게 된다.
  • 그래서 _HomeScreenState 위젯이 죽을 때는 Timer 또한 같이 죽어야된다는 명령을 입력해야한다.
  • dispose를 사용한다.
import 'dart:async';
import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  Timer? timer;

  
  void initState() {
    super.initState();

    timer = Timer.periodic(Duration(seconds: 1), (timer) {
      print('Timer');
    });
  }

  
  void dispose() {
    if (timer != null) {
      timer!.cancel();
    }

    super.dispose();
  }
// dispose는 state가 죽을 때 실행된다.
// state의 생명주기의 제일 마지막이라고 생각하면 된다.
// super.dispose(); 전에 코드를 작성해야 한다.
// Timer가 null이 아닐 때 취소를 시켜주는 코드를 작성한다.


  
  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(),
      ),
    );
  }
}

Controller 사용

  • PageView에 Controller를 집어넣어서 이 Controller로 PageView를 1초마다 조종할 수 있도록 코드를 작성해보겠다.
import 'dart:async';
import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  
  State<HomeScreen> createState() => _HomeScreenState();
}

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

  
  void initState() {
    super.initState();

    timer = Timer.periodic(Duration(seconds: 4), (timer) {
      int currentPage = controller.page!.toInt();
      // page 타입이 double인 이유는 페이지가 돌아가면서 넘겨지기 때문이다. 예들들어 반만 넘기면 0.5, 조금더 넘기면 0.7 이런식이다.
      int nextPage = currentPage + 1;

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

      controller.animateToPage(nextPage,
          duration: Duration(milliseconds: 400), curve: Curves.linear);
          // 페이지를 바꾸는 기능
    });
  }

  
  void dispose() {
    controller.dispose();
    if (timer != null) {
      timer!.cancel();
    }

    super.dispose();
  }

  
  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(),
      ),
    );
  }
}
  • PageView는 WebView와는 다르게 알아서 controller를 생성해줘야 한다.

0개의 댓글