[Flutter] 시계 기능 작성

[Flutter] 시계 기능 작성

이번에는 시계 기능이 동작하도록 변경해 볼 것입니다.

먼저 기존 코드에서 Clock 클래스를 지우고 StatefulWidget 으로 새로 작성하여 줍니다.

class Clock extends StatefulWidget {
  @override
  _ClockState createState() => _ClockState();
}

class _ClockState extends State<Clock> {
  @override
  Widget build(BuildContext context) {
    return Text("15:49", style: TextStyle(fontSize: 150),);
  }
}

intl library import

이제 외부 라이브러리를 사용할 것입니다.

Flutter 의 외부 라이브러리는 pub.dev 를 통해 모두 탐색할 수 있습니다. 이번에는 여기서 ‘intl’ 이라는 라이브러리를 사용할 것입니다.

위 사이트에서 ‘intl’ 을 검색하여 선택해 줍니다. (intl pub.dev 사이트)

이후 installing 탭을 눌러 dependecies : 밑에 작성된 코드를 복사해 줍니다.

Screenshot from 2021-04-04 15-20-59

다음으로 pubspec.yaml 파일에 들어가 아래와 같은 코드를 찾아 복사한 코드를 붙여넣기 해 줍니다.

dependencies:
  flutter:
    sdk: flutter


  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  # TODO: 아래와 같이 붙여넣기 해 줍니다.
  intl: ^0.17.0

Screenshot from 2021-04-04 15-24-07

다음으로 오른쪽 상단의 Pub get 버튼 또는 terminal 에 flutter pub get 을 작성하여 실행해 줍니다. 그러면 프로젝트에서 intl 라이브러리를 사용할 수 있게 됩니다.

Clock Widget 작성

main.dart 파일의 가장 위에 아래 코드를 작성해 줍니다.

import 'package:intl/intl_browser.dart';
import 'dart:async';

dart:async 는 Flutter 에서 Timer 기능을 사용하게 해주고, intl 라이브러리는 얻어온 값을 원하는 형태로 변경할 수 있도록 해 줍니다.

다음으로, Clock 에서 변수 2개를 생성해 줍니다. _timer 는 주기적으로 특정 함수를 실행시켜 주고, _timeString 은 현재 시간을 String 타입으로 표현한 것입니다.

class _ClockState extends State<Clock> {

  String _timeString;
  Timer _timer;

  @override
  Widget build(BuildContext context) {
    return Text(_timeString, style: TextStyle(fontSize: 150),);
  }
}

그리고 _ClockState 안에 initState 함수를 Override 하여 아래와 같이 작성해 줍니다. 이는 해당 class 안에서 initState 를 작성할 때 나오는 자동완성을 통해 작성가능합니다.

  @override
  void initState() {
    _timeString = _formatDateTime(DateTime.now());
    _timer = Timer.periodic(Duration(seconds: 1), (Timer t) => _getTime());
    super.initState();
  }

initStateStatefulWidget 이 실행될 때 딱 1번 실행되며, 여기서는 이 때 변수들에 초기값을 주도록 하였습니다. 또한 Timer 는 입력된 Duration (여기서는 1초) 마다 입력받은 함수 (여기서는 (Timer t) => _getTime()) 을 실행하는 역할을 합니다.

이제 같은방식으로 dispose 함수를 Override 하여 아래와 같이 작성해 줍니다.

  @override
  void dispose() {
    _timer.cancel();
    super.dispose();
  }

disposeStatefulWidget 이 끝나게 되면 동작하며, 여기서는 _timer 변수에 들어간 Timer 클래스 사용을 중단하여, 메모리 소모를 하지 않도록 하였습니다. 이는 주로 메모리를 많이 사용하는 변수에 대해서 사용하는 방법입니다.

다음은 현재 시간을 받아오는 함수입니다.

  void _getTime() {
    final DateTime now = DateTime.now();
    final String formattedDateTime = _formatDateTime(now);
    setState(() {
      _timeString = formattedDateTime;
    });
  }

  String _formatDateTime(DateTime dateTime) {
    return DateFormat('HH:mm').format(dateTime);
  }

DateTime.now() 는 현재 시간을 받아오고,

_formatDateTime 함수의 DateFormat('HH:mm').format(dateTime)intl 에서 지원하는 함수로 ‘HH:mm’ (24시간 형태) 의 String 타입으로 dateTime 를 변경하는 것입니다.

setState()StatefulWidget 의 새로고침과 같은 역할로, 안에 있는 함수를 실행하게 되는데, 여기서는 _timeString 값에 formattedDateTime 을 주도록 하였습니다.

위 코드가 동작하는 과정을 간단히 다시 설명하면 아래와 같습니다.

  1. initState 에서 현재시간을 _timeString 에 저장, Timer 를 생성
  2. Timer 는 1초 마다, _getTime() 실행
  3. 현재 시간을 ‘HH:mm’ 형태로 변경
  4. _timeString 에 결과를 저장
  5. build 함수에서 Text 를 통해 _timeString 을 화면에 표시
  6. Widget 종료시 Timer 종료

전체 코드는 다음과 같습니다.

class Clock extends StatefulWidget {
  @override
  _ClockState createState() => _ClockState();
}

class _ClockState extends State<Clock> {

  String _timeString;
  Timer _timer;

  @override
  void initState() {
    _timeString = _formatDateTime(DateTime.now());
    _timer = Timer.periodic(Duration(seconds: 1), (Timer t) => _getTime());
    super.initState();
  }

  @override
  void dispose() {
    _timer.cancel();
    super.dispose();
  }

  void _getTime() {
    final DateTime now = DateTime.now();
    final String formattedDateTime = _formatDateTime(now);
    setState(() {
      _timeString = formattedDateTime;
    });
  }

  String _formatDateTime(DateTime dateTime) {
    return DateFormat('HH:mm').format(dateTime);
  }

  @override
  Widget build(BuildContext context) {
    return Text(_timeString, style: TextStyle(fontSize: 150),);
  }
}

아래는 결과입니다.

Screenshot from 2021-04-04 15-48-31


© 2021. All rights reserved.