Skip to content

Instantly share code, notes, and snippets.

@haneulee
Created April 13, 2023 17:51
Show Gist options
  • Save haneulee/5c14bacc997ef86d6d04a5738ea2466e to your computer and use it in GitHub Desktop.
Save haneulee/5c14bacc997ef86d6d04a5738ea2466e to your computer and use it in GitHub Desktop.
flutter pomotimer
import 'dart:async';
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
static const int breakTime = 5;
static const int oneMinToSec = 60;
int selectedTime = 15;
int totalSeconds = 15 * oneMinToSec;
bool isRunning = false;
bool isBreaking = false;
int round = 0;
int goal = 0;
late Timer timer;
void onTick(Timer timer) {
if (totalSeconds == 0) {
if (isBreaking) {
totalSeconds = selectedTime * oneMinToSec;
isBreaking = false;
} else {
totalSeconds = breakTime * oneMinToSec;
isBreaking = true;
goal = round == 3 ? ++goal : goal;
round = round == 3 ? 0 : ++round;
}
setState(() {
isRunning = false;
});
timer.cancel();
} else {
setState(() {
totalSeconds = totalSeconds - 1;
});
}
}
String format(int seconds, String type) {
var duration = Duration(seconds: seconds);
var result =
duration.toString().split(".").first.substring(2, 7).split(":");
return type == 'min' ? result[0] : result[1];
}
void onStartPressed() {
timer = Timer.periodic(
const Duration(seconds: 1),
onTick,
);
setState(() {
isRunning = true;
});
}
void onPausePressed() {
timer.cancel();
setState(() {
isRunning = false;
});
}
void onSelectTime(int time) {
if (!isBreaking) {
setState(() {
selectedTime = time;
totalSeconds = selectedTime * oneMinToSec;
});
}
}
void onReset() {
setState(() {
totalSeconds = selectedTime * oneMinToSec;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).colorScheme.background,
body: Column(
children: [
Flexible(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
margin: const EdgeInsets.only(left: 30),
child: Text(
'POMOTIMER',
style: TextStyle(
color: Theme.of(context).cardColor,
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
),
),
Flexible(
flex: 1,
child: Container(
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Stack(
children: [
Positioned(
left: 10,
top: 0,
child: Container(
width: 100,
height: 100,
color: const Color.fromRGBO(255, 255, 255, 0.5),
),
),
Positioned(
left: 5,
top: 5,
child: Container(
width: 110,
height: 110,
color: const Color.fromRGBO(255, 255, 255, 0.7),
),
),
Container(
width: 120,
height: 120,
margin: const EdgeInsets.only(top: 10),
padding: const EdgeInsets.all(5),
alignment: Alignment.center,
decoration: const BoxDecoration(color: Colors.white),
child: Text(
format(totalSeconds, "min"),
style: TextStyle(
color: isBreaking
? Colors.green
: Theme.of(context).colorScheme.background,
fontSize: 70,
fontWeight: FontWeight.w600,
),
),
),
],
),
Container(
margin: const EdgeInsets.all(10),
child: Text(
":",
style: TextStyle(
color: Theme.of(context).cardColor,
fontSize: 60,
fontWeight: FontWeight.w600,
),
),
),
Stack(
children: [
Positioned(
left: 10,
top: 0,
child: Container(
width: 100,
height: 100,
color: const Color.fromRGBO(255, 255, 255, 0.5),
),
),
Positioned(
left: 5,
top: 5,
child: Container(
width: 110,
height: 110,
color: const Color.fromRGBO(255, 255, 255, 0.7),
),
),
Container(
width: 120,
height: 120,
margin: const EdgeInsets.only(top: 10),
padding: const EdgeInsets.all(5),
alignment: Alignment.center,
decoration: const BoxDecoration(color: Colors.white),
child: Text(
format(totalSeconds, "sec"),
style: TextStyle(
color: isBreaking
? Colors.green
: Theme.of(context).colorScheme.background,
fontSize: 70,
fontWeight: FontWeight.w600,
),
),
),
],
),
]),
),
),
SizedBox(
height: 100,
child: ListView(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.only(top: 20),
shrinkWrap: true,
children: [15, 20, 25, 30, 35].map((time) {
return Container(
margin: const EdgeInsets.all(10),
child: selectedTime == time
? TextButton(
style: TextButton.styleFrom(
foregroundColor:
const Color.fromARGB(255, 43, 36, 36),
backgroundColor: Colors.white,
),
onPressed: () => onSelectTime(time),
child: Text(
time.toString(),
style: TextStyle(
fontSize: 30,
color: Theme.of(context).colorScheme.background,
),
),
)
: OutlinedButton(
style: OutlinedButton.styleFrom(
foregroundColor:
const Color.fromARGB(255, 43, 36, 36),
backgroundColor:
Theme.of(context).colorScheme.background,
),
onPressed: () => onSelectTime(time),
child: Text(
time.toString(),
style: const TextStyle(
fontSize: 30,
color: Colors.white,
),
),
),
);
}).toList(),
),
),
Flexible(
flex: 1,
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
iconSize: 100,
color: Theme.of(context).cardColor,
onPressed: isRunning ? onPausePressed : onStartPressed,
icon: Icon(isRunning
? Icons.pause_circle_outline
: Icons.play_circle_outline),
),
IconButton(
iconSize: 100,
color: Theme.of(context).cardColor,
onPressed: onReset,
icon: const Icon(Icons.restart_alt_rounded),
),
],
)),
),
Text(
isBreaking ? 'Take a break!' : '',
style: const TextStyle(
fontSize: 40, color: Colors.green, fontWeight: FontWeight.w600),
),
Flexible(
flex: 1,
child: Row(
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(50),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'ROUND',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color:
Theme.of(context).colorScheme.background,
),
),
Text(
'$round/4',
style: TextStyle(
fontSize: 40,
fontWeight: FontWeight.w600,
color:
Theme.of(context).colorScheme.background,
),
),
],
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'GOAL',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
color:
Theme.of(context).colorScheme.background,
),
),
Text(
'$goal/12',
style: TextStyle(
fontSize: 40,
fontWeight: FontWeight.w600,
color:
Theme.of(context).colorScheme.background,
),
),
],
),
],
)),
),
],
),
)
],
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment