Skip to content

Instantly share code, notes, and snippets.

@sharryhong
Last active April 14, 2023 03:19
Show Gist options
  • Select an option

  • Save sharryhong/e63777d9ca511b938c04ddf0efa76431 to your computer and use it in GitHub Desktop.

Select an option

Save sharryhong/e63777d9ca511b938c04ddf0efa76431 to your computer and use it in GitHub Desktop.
import 'dart:async';
import 'package:flutter/material.dart';
void main() {
runApp(const App());
}
class App extends StatelessWidget {
const App({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
const HomeScreen({
super.key,
});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
static int totalSecend = 25 * 60;
static int totalRound = 4;
static int totalGoal = 12;
static int restTime = 5 * 60;
static List<String> timerTime = ['15', '20', '25', '30', '35'];
int countSecend = totalSecend;
int countRound = 0;
int countGoal = 0;
bool isRunning = false;
bool isRestTime = false;
bool isAchieveGoal = false;
Timer? timer;
String get formattedMinutes {
return (countSecend ~/ 60).toString().padLeft(2, '0');
}
String get formattedSeconds {
return (countSecend % 60).toString().padLeft(2, '0');
}
void onTick(Timer timer) {
if (countSecend != 0) {
setState(() {
countSecend--;
});
return;
}
setState(() {
if (!isRestTime) {
countSecend = restTime;
isRestTime = true;
return;
}
isRestTime = false;
countSecend = totalSecend;
countRound++;
if (countRound >= totalRound) {
countRound = 0;
countGoal++;
}
if (countGoal == totalGoal) {
timer.cancel();
isRunning = false;
isAchieveGoal = true;
}
});
}
void onStartPressed() {
timer = Timer.periodic(
const Duration(seconds: 1),
onTick,
);
setState(() {
isRunning = true;
if (isAchieveGoal) {
countGoal = 0;
isAchieveGoal = false;
}
});
}
void onPausePressed() {
timer!.cancel();
setState(() {
isRunning = false;
});
}
void onResetPressed() {
timer!.cancel();
setState(() {
isRunning = false;
countSecend = totalSecend;
countRound = 0;
countGoal = 0;
});
}
void onChangeCountSecends(String second) {
if (timer != null) timer!.cancel();
setState(() {
isRunning = false;
totalSecend = int.parse(second) * 60;
countSecend = totalSecend;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: isRestTime
? const Color.fromARGB(255, 22, 159, 129)
: const Color.fromARGB(255, 230, 77, 62),
body: Column(
children: [
Flexible(
flex: 1,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 30),
alignment: Alignment.centerLeft,
child: const Text(
'POMOTIMER',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Colors.white,
),
)),
),
Flexible(
flex: 1,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 30),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
alignment: Alignment.center,
width: 150,
height: 170,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
),
child: Text(
formattedMinutes,
style: TextStyle(
fontSize: 100,
fontWeight: FontWeight.w600,
color: isRestTime
? const Color.fromARGB(255, 22, 159, 129)
: const Color.fromARGB(255, 230, 77, 62),
),
),
),
const Text(
':',
style: TextStyle(
fontSize: 80,
fontWeight: FontWeight.w600,
color: Color.fromARGB(100, 255, 255, 255),
),
),
Container(
alignment: Alignment.center,
width: 150,
height: 170,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
),
child: Text(
formattedSeconds,
style: TextStyle(
fontSize: 100,
fontWeight: FontWeight.w600,
color: isRestTime
? const Color.fromARGB(255, 22, 159, 129)
: const Color.fromARGB(255, 230, 77, 62),
),
),
),
],
)),
),
Flexible(
flex: 1,
child: Container(
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
for (String time in timerTime)
TimeIntervalButton(
text: time,
minute: totalSecend ~/ 60,
callback: (value) => onChangeCountSecends((value)),
),
],
),
),
),
Flexible(
flex: 1,
child: Container(
alignment: Alignment.topCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
iconSize: 100,
color: Colors.white54,
icon: isRunning
? const Icon(Icons.pause_circle)
: const Icon(Icons.play_circle),
onPressed: isRunning ? onPausePressed : onStartPressed,
),
if (isRunning || countSecend != totalSecend)
IconButton(
iconSize: 100,
color: Colors.white54,
icon: const Icon(Icons.stop_circle),
onPressed: onResetPressed,
),
if (isAchieveGoal)
const Icon(
Icons.thumb_up,
size: 70,
color: Color.fromARGB(255, 255, 242, 0),
),
],
),
),
),
Flexible(
flex: 1,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
children: [
Text(
'$countRound/$totalRound',
style: const TextStyle(
fontSize: 30,
fontWeight: FontWeight.w600,
color: Color.fromARGB(100, 255, 255, 255),
),
),
const SizedBox(
height: 10,
),
const Text(
'ROUND',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
],
),
Column(
children: [
Text(
'$countGoal/$totalGoal',
style: const TextStyle(
fontSize: 30,
fontWeight: FontWeight.w600,
color: Color.fromARGB(100, 255, 255, 255),
),
),
const SizedBox(
height: 10,
),
const Text(
'GOAL',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
],
),
],
),
),
],
),
);
}
}
class TimeIntervalButton extends StatefulWidget {
final String text;
final int minute;
final Function callback;
const TimeIntervalButton({
super.key,
required this.text,
required this.callback,
required this.minute,
});
@override
State<TimeIntervalButton> createState() => _TimeIntervalButtonState();
}
class _TimeIntervalButtonState extends State<TimeIntervalButton> {
bool get isSelected {
if (widget.minute == int.parse(widget.text)) {
return true;
}
return false;
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => widget.callback(widget.text),
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 15,
vertical: 10,
),
decoration: BoxDecoration(
color: isSelected
? Colors.white
: const Color.fromARGB(0, 255, 255, 255),
border: Border.all(
width: 2,
color: Colors.white,
),
borderRadius: BorderRadius.circular(5),
),
child: Text(
widget.text,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.w700,
color: isSelected
? const Color.fromARGB(255, 230, 77, 62)
: Colors.white,
),
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment