So from past few day I have been trying to get around this logical loop, and have tried everything I could and then finally decided to post it here (hence made my debut here). I am stuck, all the help is appreciated. Thanks !
Logic: In the app there are 2 container
which displays White's and black's time, which is selected from a given five options -> 5,10,15,30,60, which then update's the time to display in those containers, used a provider
package for this and everything else.
Now I have also added a Raised button
named 'switch', which when pressed was supposed to:
- Start's the white's countdown timer
- Then if pressed again should stops white's timer and then start Black's countdown timer
- Then if pressed again should stop the black's timer and then starts white's timer.
- And repeat till the timer runs out and one out of the two is declared a winner.
Problem: So with what I coded so far, when 'switch' is pressed it starts white's timer and if pressed again stops white's timer but it doesn't begins black's timer. I know its because of the way I have framed the if() conditions and also because I don't know how to stop the timer from outside. What I have done is to use a - bool checkTimerW and checkTimerB for each white and black, which I check in the if() condition to cancel the timer is based on it.
Code:
Provider -
import 'dart:async';
import 'package:flutter/foundation.dart';
class SettingsProvider extends ChangeNotifier {
int valueW = 0;
int valueB = 0;
// * with these booleans we will stop the timer.
bool checkTimerW = true;
bool checkTimerB = true;
String timeToDisplayW = ""; // for white
String timeToDisplayB = ""; // for black
bool switchT = false;
// this is called in the settings Modal Bottom Sheet
void changeValue(int valW, int valB) {
//? Changing the value in seconds
valueW = valW * 60;
valueB = valB * 60;
print(valueW);
timeToDisplayW = valueW.toString();
timeToDisplayB = valueB.toString();
notifyListeners();
}
void reset() {
started = true;
stopped = true;
checkTimerW = false;
checkTimerB = false;
notifyListeners();
}
void toggleSwitch() {
if (switchT == false) {
switchT = true;
print('true');
} else if (switchT == true) {
switchT = false;
print('false');
}
}
void switchTimer() {
if (switchT == false) {
// Starts white's timer
Timer.periodic(
Duration(seconds: 1),
(Timer t) {
if (valueW <= 1 || checkTimerW == false) {
t.cancel();
checkTimerW = true;
// TODO : Black Won
notifyListeners();
} else {
valueW = valueW - 1;
notifyListeners();
}
timeToDisplayW = valueW.toString();
notifyListeners();
},
);
// stops black's timer
checkTimerB = false;
toggleSwitch();
notifyListeners();
} else {
// Starts black's timer
Timer.periodic(
Duration(seconds: 1),
(Timer t) {
if (valueB <= 1 || checkTimerB == false) {
t.cancel();
checkTimerB = true;
// TODO : White won
notifyListeners();
} else {
valueB = valueB - 1;
notifyListeners();
}
timeToDisplayB = valueB.toString();
notifyListeners();
},
);
// stops white's timer
checkTimerW = false;
toggleSwitch();
notifyListeners();
}
}
}
Main.dart -
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'controller/countdown_controller.dart';
import 'widgets/blackButton.dart';
import 'widgets/bottom_sheet_design.dart';
import 'widgets/whiteButton.dart';
import 'providers/settings.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
return ChangeNotifierProvider(
create: (ctx) => SettingsProvider(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.amber,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
void settings(BuildContext ctx) {
showModalBottomSheet(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
context: ctx,
builder: (_) => BottomSheetDesign(),
);
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: Colors.grey[350],
body: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
flex: 1,
child: Transform.rotate(
angle: pi / 1,
child: GestureDetector(
onTap: () {
Provider.of<SettingsProvider>(context, listen: false)
.switchTimer();
},
child: Container(
width: 80.0,
height: 500,
child: Center(
child: Transform.rotate(
angle: pi / 2,
child: Text('Switch',
style: Theme.of(context).textTheme.bodyText2),
),
),
decoration: BoxDecoration(
color: Colors.blueGrey,
),
),
),
),
),
VerticalDivider(),
Expanded(
flex: 4,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
children: <Widget>[
// container that displays black's timer
BlackButton(),
Expanded(
child: Transform.rotate(
angle: pi / 2,
child: RaisedButton(
onPressed: () {
settings(context);
},
color: Colors.blue[300],
child: Text('Settings'),
),
),
),
],
),
SizedBox(
height: 20,
),
Row(
children: <Widget>[
// container that displays white's timer
WhiteButton(),
Expanded(
child: Transform.rotate(
angle: pi / 2,
child: RaisedButton(
onPressed: () {
Provider.of<SettingsProvider>(context, listen: false).reset();
},
color: Colors.red[600],
child: Text('Reset'),
),
),
),
],
),
],
),
),
],
),
),
);
}
}