[지원 : 동국대학교 SW교육원] Flutter 앱 개발(스톱워치) part.1

2023. 12. 3. 21:10카테고리 없음

UI 작성

구현 순서 :

  1. 기본 코드 준비

  2. 시작/일시정지 버튼 영역 UI 작성

  3. 타이머 영역 UI 작성

 

기본 코드 준

import 'package:flutter/material.dart';
import 'package:obesity/main.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget{
  const MyApp({super.key});

  @override
  Widget build(BuildContext context){
    return MaterialApp(
      title: 'StopWatch',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const StopWatchPage(),
    );
  }
}

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

class _StopWatchPageState extends State<StopWatchPage>{
  ...
}

 

시작/일시정지 버튼 영역 UI 작성

Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(
        title: const Text('StopWatch'),
      ),
      body: _buildBody(),
      bottomNavigationBar: BottomAppBar(
        child: Container(
          height: 50.0,
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () => setState(() {
            _clickButton();
          }),
          child: const Icon(Icons.play_arrow),
          ),
          floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
    );
  }

  Widget _buildBody(){
    return Container();
  }

  void _clickButton(){

  }

 

 

타이머 영역 UI 작성

Widget _buildBody(){
    return Center(
      child: Padding(
        padding: const EdgeInsets.only(top: 30),
        child: Stack(
          children: <Widget>[
            Column(
              children: [
                const Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: <Widget>[
                    Text(
                      '0',
                      style: TextStyle(fontSize: 50.0),
                      ),
                      Text('00'),
                  ],
                  ),
                  SizedBox(
                    width: 100,
                    height: 200,
                    child: ListView(
                      children: const <Widget>[],
                    ),
                  )
              ],
            ),
            Positioned(
              left: 10,
              bottom: 10,
              child: FloatingActionButton(
                backgroundColor: Colors.deepOrange,
                onPressed: (){},
                child: const Icon(Icons.rotate_left),
              ),
            ),
            Positioned(
              right: 10,
              bottom: 10,
              child: ElevatedButton(
                onPressed: (){},
                child: const Text('랩타임'),
              ),
            )
          ],
        ),
      ),
    );
  }

 

타이머 구현하기

  1. Timer 클래스와 필요한 변수 준비

  2. 시작/일시정지 상태 변환 로직

  3. 시작/일시정지 동작 로직

  4. 시간 표시

  5. 시간을 표시하는 영역 UI 수정

  6. 초기화

 

Timer 클래스

import 'dart:async';

TImer.periodic(Duration(milliseconds = 10), (timer){

})

Duration(hour = 1, minutes = 30, (timer){

})

 

 

Timer 클래스와 필요한 변수 준비

class _StopWatchPageState extends State<StopWatchPage>{
  Timer _timer;

  var _time = 0;
  var _isRunning = faluse;

  List<String> _lapTimes = [];
 
 @override
  void dispose(){
    _timer?.cancel();
    super.dispose();
  }

 

 

시작/일시정지 상태 변환 로직

  void _clickButton(){
    _isRunning = ! _isRunning;

    if(_isRunning){
      _start();
    }else{
      _pause();
    }
  }
FloatingActionButton: FloatingActionButton(
    onPressed: () => setState((){
      _clickButton();
    }),
    child: _isRunning ? Icon(Icons.pause) : Icon(Icons.play_arrow),
  ),

 

 

시작/일시정지 동작 로직

void _start(){
    _timer = Timer.periodic(Duration(milliseconds: 10), (timer){
      setState((){
        _time++;
      });
    });
  }

  void _pause(){
    _timer?.cancel();
  }

 

 

시간 표시

  Widget _buildBody(){
    var sec = _time ~/100;
    var hundredth = '${_time % 100}'.padLeft(2, '0');

    return Center(

 

 

시간을 표시하는 영역 UI 수정

Row(
    mainAxisAlignment: MainAxisAlignment.center,
    crossAxisAlignment: CrossAxisAlignment.end,
    children: <Widget>[
      Text(
        '$sec',
        style: TextStyle(fontSize: 50.0),  
      ),
      Text('$hundredth')
    ],
  ),

 

 

초기화

  Positioned(
    left = 10,
    bottom = 10,
    child = FloatingActionButton(
      backgroundColor: Colors.deepOrange,
      onPressed: reset,
      child: const Icon(Icons.rotate_left),
    ),
  ),
  void _reset(){
    setState(() {
      _isRunning = false;
      _timer?.cancel();
      _lapTimes.clear();
      _time = 0;
    });
  }