Reputation: 33
So I am new to Flutter and I want to make a simple scoreboard with its timer and everything. The problem is that I got two files screen_result and time. In screen_result I have a screen and buttons to operate the scoreboard, in time I have a stopwatch and its control buttons in it.
What I want is to call separately widget build Time below score and widget build Buttons next to other buttons for controlling scoreboard. I do that but nothing happens when I press button to start time. So I am doing something wrong but don't know what.
screen_result.dart
import 'package:flutter/material.dart';
import 'time.dart';
class Screen extends StatefulWidget {
@override
_ScreenState createState() => _ScreenState();
}
class _ScreenState extends State<Screen> {
int result_home = 0;
int result_away = 0;
Widget build(BuildContext context) {
return new Scaffold(
body: SingleChildScrollView(
child: Column(children: <Widget>[
Row(
//ROW 1
mainAxisAlignment: MainAxisAlignment.center,
children: [
//-------------------------RESULT HOME
Container(
color: Colors.green,
margin: EdgeInsets.all(0.0),
height: 500,
width: 300,
alignment: Alignment.topCenter,
child: new Text(
'$result_home',
style: new TextStyle(
fontSize: 100.0,
color: Colors.white,
),
),
),
//------------------------TIME SPACE
Column(
children: [
Container(
color: Colors.green,
margin: EdgeInsets.all(0.0),
height: 150,
width: 450,
alignment: Alignment.topCenter,
child: new Text(
':',
style: new TextStyle(
fontSize: 100.0,
color: Colors.white,
),
),
),
Container(
color: Colors.green,
margin: EdgeInsets.all(0.0),
height: 350,
width: 450,
alignment: Alignment.topCenter,
child: TimeState().buiildTime(),
),
],
),
//-------------------------------RESULT AWAY
Container(
color: Colors.green,
margin: EdgeInsets.all(0.0),
height: 500,
width: 300,
alignment: Alignment.topCenter,
child: new Text(
'$result_away',
style: new TextStyle(
fontSize: 100.0,
color: Colors.white,
),
),
),
],
),
Row(//ROW 2
children: [
Flexible(
fit: FlexFit.tight,
flex: 1,
child: Container(
color: Colors.blue,
height: 200,
child: Column(
children: [
SizedBox(
width: 150,
height: 100,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.yellow[700],
onPrimary: Colors.red,
),
onPressed: () {
setState(() {
result_home++;
});
},
child: new Text(
"GOAL HOME",
style: new TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
SizedBox(
width: 150,
height: 100,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.yellow[700],
onPrimary: Colors.red,
),
onPressed: () {
if (result_home > 0) {
setState(() {
result_home--;
});
}
},
child: new Text(
"NO GOAL",
style: new TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
],
)),
),
Flexible(
fit: FlexFit.tight,
flex: 1,
child: Column(
children: [
Container(
width: 150,
height: 100,
child: TimeState().buildButtons()
),
],
),
),
Flexible(
fit: FlexFit.tight,
flex: 1,
child: Container(
color: Colors.blue,
height: 200,
child: Column(
children: [
SizedBox(
width: 150,
height: 100,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.yellow[700],
onPrimary: Colors.red,
),
onPressed: () {
setState(() {
result_away++;
});
},
child: new Text(
"GOAL AWAY",
style: new TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
SizedBox(
width: 150,
height: 100,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.yellow[700],
onPrimary: Colors.red,
),
onPressed: () {
if (result_away > 0) {
setState(() {
result_away--;
});
}
},
child: new Text(
"NO GOAL",
style: new TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
],
)),
),
]),
])));
}
}
time.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'button.dart';
class Time extends StatefulWidget {
@override
State<Time> createState() => TimeState();
}
class TimeState extends State<Time> {
Duration duration = Duration();
Timer? timer;
late String time;
final myController = TextEditingController();
@override
void initState() {
super.initState();
reset();
}
void reset() {
setState(() => duration = Duration());
}
void addTime() {
final addSeconds = 1;
setState(() {
final seconds = duration.inSeconds + addSeconds;
duration = Duration(seconds: seconds);
time = duration.toString();
});
}
void startTimer({bool resets = true}) {
if (resets) {
reset();
}
timer = Timer.periodic(Duration(seconds: 1), (_) => addTime());
}
void stopTimer({bool resets = true}) {
if (resets) {
reset();
}
setState(() {
timer?.cancel();
});
}
void firstHalfEnd() {
setState(() => duration = Duration(minutes: 45, seconds: 00));
stopTimer(resets: false);
}
void secondHalfEnd() {
setState(() => duration = Duration(minutes: 90, seconds: 00));
stopTimer(resets: false);
}
void addMinute (){
setState(() {
duration = duration + Duration(minutes: 1);
});
}
void subtractMinute (){
setState(() {
duration = duration - Duration(minutes: 1);
});
}
@override
Widget build(BuildContext context) => Scaffold(
backgroundColor:
Colors.green,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
buiildTime(),
SizedBox(
height: 20,
),
buildButtons()
],
)),
);
Widget buiildTime() {
String twoDigits(int n) => n.toString().padLeft(
2, '0'); // pretvara jednoznamenkaste brojeve u "dvoznamenkaste" 9 -> 09
final minutes = twoDigits(duration.inMinutes.remainder(100));
final seconds = twoDigits(duration.inSeconds.remainder(60));
return Text(
'$minutes:$seconds',
style: TextStyle(fontSize: 20),
);
}
Widget buildButtons() {
bool time_going = timer == null ? false : timer!.isActive;
bool time_stops = duration.inSeconds == 0;
return time_going || !time_stops
? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
ButtonWidget(
text: time_going ? 'PAUSE' : 'RESUME',
onClicked: () {
if (time_going) {
stopTimer(resets: false);
} else {
startTimer(resets: false);
}
}),
SizedBox(
width: 12,
),
ButtonWidget(text: "RESET", onClicked: reset,),
],
),
SizedBox(
height: 10,
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
ButtonWidget(
text : '1. Half END',
color: Colors.white,
backgroundColor: Colors.blue,
onClicked: firstHalfEnd,
),
SizedBox(width: 10,),
SizedBox(
child:ButtonWidget(
text : '2. Half END',
color: Colors.white,
backgroundColor: Colors.blue,
onClicked: secondHalfEnd,
)),
],
),
Row(
children: [
ElevatedButton(onPressed: addMinute, child: Text('+1 minute')),
SizedBox(width: 10,),
ElevatedButton(onPressed: subtractMinute, child: Text('-1 minute'))
],
)
],
)
: ButtonWidget(
text: "Start Timer!",
color: Colors.black,
backgroundColor: Colors.white,
onClicked: () {
startTimer();
});
}
}
button.dart
import 'package:flutter/material.dart';
class ButtonWidget extends StatelessWidget {
final String text;
final Color color;
final Color backgroundColor;
final VoidCallback onClicked;
const ButtonWidget({Key? key, required this.text, required this.onClicked,
this.color = Colors.white, this.backgroundColor = Colors.black}) : super(key: key);
@override
Widget build(BuildContext context) => ElevatedButton(
style: ElevatedButton.styleFrom(
primary: backgroundColor,
padding: EdgeInsets.symmetric(horizontal: 32, vertical: 16)
),
onPressed: onClicked,
child: Text(text,style: TextStyle(fontSize: 15,color: color),)
);
}
Upvotes: 0
Views: 843
Reputation: 502
Since you are new to Flutter
, I would like to give you some tips.
1- There is no need to use the new
prefix in the Dart
language.
2- Instead, try to use const
where needed.
3- To name variables, prefer camelCase
, not snake_case
.
4- Prefer SizedBox
over Container
when you need to assign height
or width
only.
5- Check default
values, and try not to override properties unnecessarily.
6- Prefer to use interpolation
to compose strings and values. So do not use toString
.
7- You should make your Child's widgets(Time
, Button
) stateless, as their states are handled by the parent(Screen
).
If we come to the problem that you faced, you are calling a widget from another State like the following:
child: TimeState().buiildTime(),
Instead, create separate widgets for different needs like you did in button.dart
.
So take all your addTime
, resetTime
, etc. methods and put in to screen.dart
and create two different child widget(TimeScore, TimeControlButtons).
If you have further questions, please don't hesitate to write in the comments.
Upvotes: 1