[Flutter/Dart] Timer, State 써보까?~

houndhollis·2023년 11월 16일
1
post-thumbnail

토요일날 일본 간다.. 두근두근 ❣️

Timer

오늘은 간단하게 타이머 이용해서

아주 간단하게 만들어 볼려고 한다. 우선
StatefulWidget 으로 선언해준다.

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

class TimerScreen extends StatefulWidget {
  const TimerScreen({super.key});

  @override
  State<TimerScreen> createState() => _TimerScreenState();
}

class _TimerScreenState extends State<TimerScreen> {
  late Timer timer;
  int seconds = 0;
  bool isRun = false;

  @override
  Widget build(BuildContext context) {
    final ts = TextStyle(
      fontSize: 20.0,
    );

    return Scaffold(
      body: Center(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 24.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Align(
                alignment: Alignment.center,
                child: Text(
                  '시간 이 가는중! $seconds 초',
                  style: const TextStyle(
                    fontSize: 30.0,
                    fontWeight: FontWeight.w600,
                  ),
                ),
              ),
              const SizedBox(height: 16.0),
              ElevatedButton(
                onPressed: () {
                  if (isRun) {
                    setState(() {
                      isRun = false;
                      timer.cancel();
                    });
                  } else {
                    setState(() {
                      isRun = true;
                      timer = Timer.periodic(Duration(seconds: 1), (timer) {
                        setState(() {
                          seconds ++;
                        });
                      });
                    });
                  }
                },
                child: Text(
                  isRun ? '중지 하겠습니다!' : '시작 하겠습니다!',
                  style: ts,
                ),
              ),
              ElevatedButton(
                onPressed: () {
                  setState(() {
                    isRun = false;
                    timer!.cancel();
                    seconds = 0;
                  });
                },
                child: Text(
                  '초기화',
                  style: ts,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

조금 두서 없이 작성한거 같아 코드가 지저분 하다. 일단은 전체 코드이다.

class _TimerScreenState extends State<TimerScreen> {
  late Timer timer;
  bool isRun = false;
  int seconds = 0;

두개의 클래스중 State쪽에다가 작성해준다. 나는 Timer를 널러블 하게 해도 상관없지만.
late 키워드는 변수를 나중에 초기화할 것임을 표시한다. 컴파일러에게 해당 변수가 나중에 초기화될 것이며 사용 전에 초기화될 것이라고 알려주는 역할이다.

isRun 이라는 bool 값으로 Text, onPressed 를 제어한다.

이런 느낌으로 Text 제어가 가능하다 이거를 우리는 삼항 연산자 라고 부르기로 했다.

우선 Timer 부터 보면 Timer 클래스를 이용해서 timer 선언을 해주고
'시작 하겠습니다!' 를 클릭 하는 순간

Timer 안에 periodic 을 사용하여 Duration 값으로 지정한 시간 마다 timer 함수 안으로 카운트가 찍힌다.
우리는 여기서 setState를 이용하여 int 0 으로 설정한 seconds를 1씩 증가해준다.

이렇게 했을 경우

  • 시작 하겠습니다 -> 중지 하겠습니다 라고 변경이 된다.


중지 하겠습니다 의 클릭 부분이다.
어느정도 개발을 하는 사람은 간단하게 생각 할수 있다, 하지만 정말 힘든 작업이다.

if (timer != null) {
  setState(() {
    isRun = false;
    timer!.cancel();
    seconds = 0;
  });
}

초기화 부분은 이렇게 된다.
여기서 timer 값을 보면, null이 아닐때 실행 시켜주면 된다.

이로써 우리는 Timer를 동작 시켜봤다 하지만 사실 여기엔 크나큰 오류가 있다.
사실 late로 선언하여 timer를 초기화 나중에 한다고 선언했을 경우 초기화가 되지 않은 상태에서 '초기회' button을 클릭 했을 경우 이니셜라이즈 에러가 발생한다. 그래서 나는 Timer? timer; 로 변경 하여 코드를 작성 해서 문제를 해결해줬다. 여기서 얻은 교훈 조만간 상황에 따라서 late, ? 비슷해 보이는데 어떤 상황에서 사용하는지에 대해서 작성을 해볼까 한다.

우선 여행다녀오겠습니다.

profile
한 줄 소개

0개의 댓글