Reputation: 7122
I followed a Flutter tutorial that builds a stopwatch.
The app builds and runs, however I can't get it to update the hours(HRS) and minutes(MIN) part of the widget. It only updates the seconds(SEC).
I've tried moving pieces of the code around and debugging, but I only end up breaking the whole thing so it doesn't run at all.
Here is a screenshot of what I mean:
Here is the app:
import 'package:flutter/material.dart';
import 'dart:async';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new TimerAppState();
}
}
class TimerAppState extends State<MyApp> {
static const duration = const Duration(seconds: 1);
int secondsPassed = 0;
bool isActive = false;
Timer timer;
void handleTick() {
if(isActive) {
setState(() {
secondsPassed = secondsPassed + 1;
});
}
}
@override
Widget build(BuildContext context) {
if (timer == null)
timer = Timer.periodic(duration, (Timer t)
{
handleTick();
});
int seconds = secondsPassed * 60;
int minutes = secondsPassed ~/ 60;
int hours =secondsPassed ~/ (60 * 60);
return MaterialApp(
title: 'Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Timer'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CustomTextContainer(label: 'HRS', value: hours.toString().padLeft(2, '0')),
CustomTextContainer(label: 'MIN', value: minutes.toString().padLeft(2, '0')),
CustomTextContainer(label: 'SEC', value: seconds.toString().padLeft(2, '0')),
],
),
Container(
margin:EdgeInsets.only(top: 20),
child:RaisedButton(
child: Text(isActive ? 'STOP' : 'START'),
onPressed: () {
setState(() {
isActive = !isActive;
});
},
),
),
],
),
),
)
);
}
}
class CustomTextContainer extends StatelessWidget {
CustomTextContainer({this.label, this.value});
final String label;
final String value;
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 5),
padding: EdgeInsets.all(20),
decoration: new BoxDecoration(
borderRadius: new BorderRadius.circular(10),
color: Colors.black87,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'$value',
style: TextStyle(
color: Colors.white,
fontSize: 34,
fontWeight: FontWeight.bold
),
),
Text(
'$label',
style: TextStyle(
color: Colors.white70,
),
)
],
),
);
}
}
Is there anyway to get this to work properly?
Thanks!
Upvotes: 3
Views: 5295
Reputation: 11
Use som modulos %
int seconds = secondsPassed % 60;
int minutes = secondsPassed ~/ 60 % 60;
int hours = secondsPassed ~/ (60 * 60) % 24;
Upvotes: 1
Reputation: 1148
you have to add all updated values inside setState
method not just seconds
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new TimerAppState();
}
}
class TimerAppState extends State<MyApp> {
static const duration = const Duration(seconds: 1);
int secondsPassed = 0;
bool isActive = false;
Timer timer;
int seconds, minutes, hours;
@override
void initState() {
super.initState();
if (timer == null)
timer = Timer.periodic(duration, (Timer t) {
handleTick();
});
}
void handleTick() {
if (isActive) {
setState(() {
secondsPassed = secondsPassed + 1;
seconds = secondsPassed * 60;
minutes = secondsPassed ~/ 60;
hours = secondsPassed ~/ (60 * 60);
});
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Timer'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CustomTextContainer(
label: 'HRS', value: hours.toString().padLeft(2, '0')),
CustomTextContainer(
label: 'MIN',
value: minutes.toString().padLeft(2, '0')),
CustomTextContainer(
label: 'SEC',
value: seconds.toString().padLeft(2, '0')),
],
),
Container(
margin: EdgeInsets.only(top: 20),
child: RaisedButton(
child: Text(isActive ? 'STOP' : 'START'),
onPressed: () {
setState(() {
isActive = !isActive;
});
},
),
),
],
),
),
));
}
}
class CustomTextContainer extends StatelessWidget {
CustomTextContainer({this.label, this.value});
final String label;
final String value;
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 5),
padding: EdgeInsets.all(20),
decoration: new BoxDecoration(
borderRadius: new BorderRadius.circular(10),
color: Colors.black87,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'$value',
style: TextStyle(
color: Colors.white, fontSize: 34, fontWeight: FontWeight.bold),
),
Text(
'$label',
style: TextStyle(
color: Colors.white70,
),
)
],
),
);
}
}
Upvotes: 5