2024. 8. 15. 04:17ㆍFlutter
오늘은 플러터에서 Timer를 만들어보았다
처음에는 어떻게 만들어야 할 지 잘 모르겠어서 블로그를 찾아봤는데
Timer만 있거나 또는 CircularProgressIndicator만 활용해서 구현한 타이머들 밖에 볼 수 없었다
하지만 나는 그 두가지를 다 이용하여 구현을 해야했기 때문에
한 번 구현을 해보았다!
우선 가장 먼저
내가 몇 분을 지정할 것인지와 타이머 객체등을 만들어줬다
static const maxSecond = 1500; //25분
int remainingSecond = maxSecond; // 남은 시간
Timer? _timer;
bool isRunning = false;
옆에 주석을 보면 이해가 편할 거 같다
다음으로는 버튼을 통해서 타이머를 시작해줄 것이기 때문에
함수를 하나 만들어줬다
void startTimer(){
_timer = Timer.periodic(Duration(seconds: 1), (timer){
setState(() {
if (remainingSecond > 0) {
remainingSecond--; //남은 시간을 1초씩 줄인다
}
else{
_timer?.cancel(); //시간이 0이되면 타이머 중지
}
});
});
}
위의 코드처럼 남은 시간(remainingSecond)이 0보다 클 경우
남은 시간을 1초씩 줄이고
만약 그렇지 않다면 타이머를 중지 시킨다
이후 우리 프로젝트에서는 타이머를 중지 시켰다가 다시 실행을 시켜야 하기 때문에
함수를 하나 더 만들어줬다
void toggleTimer(){
if (isRunning) {
//타이머를 일시 정지
_timer?.cancel();
} else{
//재시작
startTimer();
}
setState(() {
isRunning = !isRunning;
});
}
위의 코드처럼 타이머가 isRunning 즉 실행 중일 때 버튼을 누르면 타이머를 중지시키고
isRunning이 아닐 때에는 재시작을 시켜주는 함수이다
다음으로는 우리가 시간을 1500초로 지정했으니 이걸 시간으로 바꿔주는 함수를 만들어줬다
String formatTime(int seconds){
int minutes = seconds ~/ 60;
int sec = seconds % 60;
return '${minutes.toString().padLeft(2, '0')}:${sec.toString().padLeft(2, '0')}';
}
위의 코드처럼 seconds를 매개변수로 받고
받아온 seconds를 통해서 우리가 아는 시간으로 바꿔준다
이제는 CircularProgressIndicator를 사용해보자
CircularProgressIndicator(
backgroundColor: Colors.cyanAccent,
strokeWidth: 20,
value: remainingSecond / maxSecond , //점점 줄어들게끔 구현
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
위의 코드를 보면 background 색을 지정해줬고
value에 시간이 점점 줄어들게끔 구현을 해준다
또한 valueColor를 통해서 시간이 줄어드는 것을 직관적으로 확인할 수 있게 해준다
마지막으로 타이머를 중지, 실행 시킬 수 있는 버튼을 봐보도록 하자
IconButton(
onPressed: toggleTimer,
iconSize: 60,
icon: Icon(
isRunning
? Icons.pause
: Icons.play_arrow,
color: Colors.white,
),
)
이렇게 구현을 해줬다
위에서 만들었던 toggleTimer를 지정해주고
icon은 상태에 따라서 바뀌어야 하기 때문에
저렇게 지정을 해줬다
이건 전체 코드이다!
class TimerScreen extends StatefulWidget {
const TimerScreen({super.key});
@override
State<TimerScreen> createState() => _TimerScreenState();
}
class _TimerScreenState extends State<TimerScreen> with TickerProviderStateMixin {
static const maxSecond = 1500; //25분
int remainingSecond = maxSecond; // 남은 시간
Timer? _timer;
bool isRunning = false;
@override
void dispose() {
// TODO: implement dispose
_timer?.cancel();
super.dispose();
}
void startTimer(){
_timer = Timer.periodic(Duration(seconds: 1), (timer){
setState(() {
if (remainingSecond > 0) {
remainingSecond--; //남은 시간을 1초씩 줄인다
}
else{
_timer?.cancel(); //시간이 0이되면 타이머 중지
}
});
});
}
void toggleTimer(){
if (isRunning) {
//타이머를 일시 정지
_timer?.cancel();
} else{
//재시작
startTimer();
}
setState(() {
isRunning = !isRunning;
});
}
//시간 변환
String formatTime(int seconds){
int minutes = seconds ~/ 60;
int sec = seconds % 60;
return '${minutes.toString().padLeft(2, '0')}:${sec.toString().padLeft(2, '0')}';
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black12,
body: SafeArea(
child: Container(
padding: EdgeInsets.all(20),
margin: EdgeInsets.fromLTRB(0, 30, 0, 0),
child: Align(
alignment: Alignment.center,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text("경영시험 공부하기에", style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white, fontSize: 18),),
Text("일단 딱 25분 만 집중해보아요!", style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white, fontSize: 18)),
SizedBox(height: 50,),
Center(
child: SizedBox(
width: 300,
height: 300,
child: Stack(
fit: StackFit.expand,
children: [
CircularProgressIndicator(
backgroundColor: Colors.cyanAccent,
strokeWidth: 20,
value: remainingSecond / maxSecond , //점점 줄어들게끔 구현
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("남은 시간", style: TextStyle(fontSize: 20),),
Text(
formatTime(remainingSecond),
style: TextStyle(fontSize: 50, color: Colors.lightGreenAccent),
),
IconButton(
onPressed: toggleTimer,
iconSize: 60,
icon: Icon(
isRunning
? Icons.pause
: Icons.play_arrow,
color: Colors.white,
),
)
],
)
)
],
),
),
)
],
),
),
),
),
);
}
}
'Flutter' 카테고리의 다른 글
Flutter Firebase 데이터 update (데이터 수정) (3) | 2024.11.01 |
---|---|
Flutter Firebase 저장(Riverpod 활용) (8) | 2024.10.27 |
[flutter] CupertinoDatePicker를 활용하여 시간 선택 (1) | 2024.09.11 |
Flutter 리스트 드래그해서 위치 바꾸기(ReorderableListView) (0) | 2024.08.10 |
Flutter build 오류 해결,, (0) | 2024.07.26 |