뽀모도로는 집중 시간을 일정한 단위로 나누어 작업하는 시간 관리 기법이다. 기본 방식은 25분 집중 + 5분 휴식으로 구성되는데, 25분 동안 한 가지 일에만 집중하고, 그 후 5분간 쉬는 것이다. 해당 앱은 25분의 타이머 기능과 25분이 지나면 뽀모도로 횟수가 1 증가하는 기능을 포함한다.
1. Flexible
Flexible 위젯은 Flutter에서 레이아웃을 구성할 때 자식 위젯들이 차지하는 공간을 유연하게 배분하는 데 사용된다. flex값을 통해 각 영역의 크기를 조절한다. 전체를 flex로 설정한 비율로 공간을 할당하는 방식이다.
뽀도모로 앱의 UI는 크게 세 부분으로 구성된다.
(1) 타이머
(2) 시작 버튼
(3) 뽀도모로 횟수 체크
이 이외의 부분은 필요 없기 때문에 flexible 위젯을 활용하여 공간을 할당한다.
2. Expanded
Expanded 위젯은 남은 공간을 모두 차지하게 한다. Flexible의 하위 클래스이기 때문에 기본적으로 동일한 기능을 하지만 Expanded는 주로 부모 위젯의 남은 공간을 모두 차지하고 싶을 때 사용한다.
해당 코드는 뽀도모로 횟수 체크하는 부분의 flexible위젯의 일부이다. Expanded 위젯으로 감싼 부분이 Expanded의 부모 위젯인 Flexible을 가득 채우기 위해 사용되었다.
3. Timer *사용하려면 import dart:async
Timer는 주어진 시간 간격으로 특정 작업을 반복하거나 일정 시간이 지난 후 한번만 실행하도록 설정할 수 있는 기능을 제공한다. 주요 클래스는 Timer, Timer.periodic 두가지이다.
Timer : 한 번만 실행되는 타이머로 일정 시간 후 작업을 실행한다. ---> 25분 이후 뽀도모로 횟수 1 증가
Timer.periodic : 지정된 간격으로 주기적으로 반복되는 타이머를 실행한다. ---> 1초마다 타이머 갱신
String format(int seconds) {
var duration = Duration(seconds: seconds);
return duration.toString().split(".").first.substring(2, 7);
}
- Duration 클래스는 특정 시간 간격을 나타내는 클래스다. seconds 매개변수를 통해 전달된 초 값으로 Duration 객체를 생성한다. seconds = 1500이면 Duration 객체는 25분을 나타내게 된다.
- Duration 객체의 toString() 메소드는 hh:mm:ss.sss 형식의 문자열을 반환한다.
- Duration.toString()은 hh:mm:ss.sss 형식의 문자열을 반환하므로, 이를 "." 기준으로 나누면 "." 앞 부분(시:분:초)과 뒤 부분(밀리초)"으로 나뉜다.
- .split(".")는 문자열을 . 기준으로 나누고, .first는 . 앞의 부분만 가져온다. 즉, hh:mm:ss 부분만 가져오게 된다.
예를 들어, 0:25:00.000000을 split(".")으로 나누면, ["0:25:00", "000000"] 배열이 되며, first는 0:25:00을 반환한다. - substring(2, 7)은 문자열에서 인덱스 2부터 7까지의 부분 문자열을 반환한다.
0:25:00 문자열에서 substring(2, 7)을 호출하면 25:00이 반환된다.
(1) 시작 버튼을 누르면 타이머가 작동해야한다.
void onStartPressed() {
timer = Timer.periodic(
const Duration(seconds: 1), // 1초 간격
onTick, // onTick 함수가 매초 호출됨
);
setState(() {
isRunning = true; // 타이머가 실행 중임을 표시
});
}
//UI
IconButton(
iconSize: 120,
color: Theme.of(context).cardColor,
onPressed: isRunning ? onPausePressed : onStartPressed, // 타이머가 실행 중이면 일시정지, 아니면 시작
icon: Icon(
isRunning ? Icons.pause_circle_outline : Icons.play_circle_outline, // 타이머 실행 여부에 따라 아이콘 변경
),
)
- Timer.periodic을 사용하여 매초마다 onTick 함수가 호출되고, setState로 isRunning을 true로 설정하여 UI에서 타이머가 실행 중임을 표시한다.
- onPressed: isRunning 상태에 따라 onPausePressed 또는 onStartPressed를 호출한다. 타이머가 실행 중이면 일시 정지 버튼을, 실행되지 않으면 시작 버튼을 활성화한다.
- icon: 타이머가 실행 중일 때는 "일시 정지" 아이콘 (pause_circle_outline)을, 실행되지 않을 때는 "시작" 아이콘 (play_circle_outline)을 표시한다.
(2) 시작 버튼을 한번 더 누르면 타이머가 멈춰야 한다.
void onPausePressed() {
timer.cancel(); // 타이머 취소
setState(() {
isRunning = false; // 타이머가 중지된 상태로 표시
});
}
//UI
IconButton(
iconSize: 120,
color: Theme.of(context).cardColor,
onPressed: isRunning ? onPausePressed : onStartPressed, // 타이머가 실행 중이면 일시 정지, 아니면 시작
icon: Icon(
isRunning ? Icons.pause_circle_outline : Icons.play_circle_outline, // 타이머 실행 여부에 따라 아이콘 변경
),
)
- timer.cancel()을 호출하면 Timer.periodic이 더 이상 호출되지 않아 타이머가 멈춘다.
- setState로 UI를 갱신하여 타이머가 멈췄음을 보여준다.
- 타이머가 실행 중이면 onPausePressed를 호출하여 타이머를 멈추고, 그렇지 않으면 onStartPressed를 호출해 타이머를 시작한다.
(3) 25분이 지나면 타이머는 초기 시간으로 리셋되어야 한다.
void onTick(Timer timer) {
if (totalSeconds == 0) {
setState(() {
totalPomodoros += 1; // Pomodoro 횟수 증가
totalSeconds = twentyFiveMinutes; // 시간을 25분으로 리셋
});
timer.cancel(); // 타이머 중지
} else {
setState(() {
totalSeconds -= 1; // 1초씩 시간 차감
});
}
}
- onTick에서 totalSeconds가 0이 되면, setState로 Pomodoro 횟수를 1 증가시키고 시간을 초기화한다.
- timer.cancel()로 타이머를 중지시켜, 타이머가 더 이상 작동하지 않도록 한다.
(4) 25분이 지나면 뽀도모로 횟수를 1 증가시켜야 한다.
if (totalSeconds == 0) {
setState(() {
totalPomodoros += 1; // Pomodoro 횟수 증가
totalSeconds = twentyFiveMinutes; // 시간을 25분으로 리셋
});
timer.cancel(); // 타이머 중지
}
- 타이머가 종료될 때마다 Pomodoro 횟수를 증가시켜서 UI에 반영한다.
5. Restart button
재시작 버튼은 타이머를 25분으로 초기화하고, 타이머를 멈추는 역할을 한다.
void onRestartPressed() {
timer.cancel(); // 타이머 취소
setState(() {
totalSeconds = twentyFiveMinutes; // 타이머를 25분으로 초기화
isRunning = false; // 타이머가 멈춘 상태로 표시
});
}
- timer.cancel을 이용해 우선 타이머를 취소시킨다.
- setState을 이용해 UI상태를 변화시킨다. 타이머를 25분으로 초기화 하고 타이머가 멈춘 상태로 표시되도록 isRunning 을 false로 설정한다.
- 시작 버튼이 포함된 flexible 위젯에 Icon 버튼을 추가하여 해당 함수를 연결한다.
'Group Study (2024-2025) > Flutter' 카테고리의 다른 글
[Flutter] 5주차 스터디_Widget State 이해하기 (0) | 2024.11.13 |
---|---|
[Flutter] 4주차 스터디_UI 구성하기 (0) | 2024.10.29 |
[Flutter] 3주차 스터디_Flutter 시작하기 (8) | 2024.10.12 |
[Flutter] 2주차 스터디_비동기 프로그래밍(Async Programming ) (1) | 2024.10.09 |
[Flutter] 1주차 스터디_함수형 프로그래밍 (Functional Programming) (11) | 2024.09.30 |