How do i set the value of toggle buttons within teams? - flutter

How do i set the value of the toggle score buttons for each team ?
For example when team A is pressed then user can choose from score buttons. Also if team B is pressed then user can choose from score buttons. But only the team selected gets the points.
void scoreTeamA() {
setState(() {
outputTeamA += _choiceA;
});
}
void scoreTeamB() {
setState(() {
outputTeamB += _choiceB;
});
}
Team buttons
ToggleButtons(
children: [
Container(
child: Text(
'team A',
textScaleFactor: 3,
),
),
Text(
'team B ',
textScaleFactor: 3,
),
],
onPressed: (int index) {
setState(() {
for (int buttonIndex = 0;
buttonIndex < isSelected1.length;
buttonIndex++) {
if (buttonIndex == index) {
isSelected1[buttonIndex] = true;
} else {
isSelected1[buttonIndex] = false;
}
}
});
},
Score buttons
ToggleButtons(
children: [
Text('5 points'),
Text('6 points'),
Text('7 points'),
],
onPressed: (int index) {
setState(() {
isSelected2[index] = !isSelected2[index];
switch (index) {
case 0:
_choiceA = 5;
_choiceB = 5;
break;
case 1:
_choiceA = 6;
_choiceB = 6;
break;
case 2:
_choiceA = 7;
_choiceB = 7;
break;
}
});
},
isSelected: isSelected2,
),
Win Button
MaterialButton(
shape: CircleBorder(
side: BorderSide(
color: Colors.black,
width: 1.0,
style: BorderStyle.solid)),
color: Colors.blue,
onPressed: () {
setState(() {
scoreTeamA();
scoreTeamB();
});
},
child: Text(
'win',
textScaleFactor: 3,
),
),

Okay I believe this is what you are looking for I want to explain some things because I ended up having to change a little bit more than what your question asked because other problems presented themselves once i got the logic you wanted working so here is the code.
Also sorry about the extra styling you can take it out.
int outputTeamA = 0;
int outputTeamB = 0;
List<bool> isSelected1 = [false, false];
List<bool> isSelected2 = [false, false, false];
int _choiceA = 0;
int _choiceB = 0;
void scoreTeamA() {
setState(() {
outputTeamA += _choiceA;
});
}
void scoreTeamB() {
setState(() {
outputTeamB += _choiceB;
});
}
#override
Widget build(BuildContext context) {
ToggleButtons toggleButtons = ToggleButtons(
borderRadius: BorderRadius.circular(30),
borderColor: Colors.pink,
children: [
Container(
padding: EdgeInsets.all(8.0),
child: Text(
'Team A',
textScaleFactor: 3,
),
),
Text(
'Team B ',
textScaleFactor: 3,
),
],
onPressed: (int index) {
setState(
() {
for (int buttonIndex = 0;
buttonIndex < isSelected1.length;
buttonIndex++) {
if (buttonIndex == index) {
isSelected1[buttonIndex] = true;
} else {
isSelected1[buttonIndex] = false;
}
}
},
);
},
isSelected: isSelected1,
);
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
toggleButtons,
SizedBox(height: 20),
ToggleButtons(
borderColor: Colors.pink,
borderRadius: BorderRadius.circular(30),
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('5 points'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('6 points'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text('7 points'),
),
],
onPressed: (int index) {
setState(() {
isSelected2[index] = !isSelected2[index];
switch (index) {
//This is the other area I had to make changes
case 0:
if (isSelected2[index]) {
print('true');
_choiceA += 5;
_choiceB += 5;
} else {
print('false');
_choiceA += -5;
_choiceB += -5;
}
break;
case 1:
if (isSelected2[index]) {
_choiceA += 6;
_choiceB += 6;
} else {
_choiceA += -6;
_choiceB += -6;
}
break;
case 2:
if (isSelected2[index]) {
_choiceA += 7;
_choiceB += 7;
break;
} else {
_choiceA += -7;
_choiceB += -7;
break;
}
}
});
},
isSelected: isSelected2,
),
SizedBox(height: 20),
MaterialButton(
shape: CircleBorder(
side: BorderSide(
color: Colors.black,
width: 1.0,
style: BorderStyle.solid)),
color: Colors.blue,
onPressed: () {
//This is the logic you wanted
if (isSelected1[0]) {
setState(() {
scoreTeamA();
});
} else if (isSelected1[1]) {
setState(() {
scoreTeamB();
});
}
print('TeamA: $outputTeamA');
print('TeamB: $outputTeamB');
},
child: Text(
'win',
textScaleFactor: 3,
),
),
],
)),
),
);
}
Once I added the logic you wanted I noticed that if the user selected and un-selected a score then pressed 'I Win' the app acted as though that score was still selected so thats why I made the other changes I made now I don't know if you want to allow more than one score to be selected at a time right now thats how you had the logic set up so thats the route I went. If this is not how you want it to work it shouldn't be that hard to switch some of this logic around. So in conclusion if multiple scores are selected they get added together.

Related

Need to keep old values when I comeback from the second screen

I’m making a pomodoro timer app. When I go to the SettingsScreen and come back to the home screen it reset the setNum value to 0 and the done value to 0.
I need to keep those previous values when I come back from the SettingsScreen.
In the settings screen, If I changed
Navigator.of(context).push(MaterialPageRoute()
To this
Navigator.of(context).pop(MaterialPageRoute()
In home screen, it will keep the previous values and it won’t change setNum to 0 but then I cannot change Times from that screen.
How to solve this?
Home Screen
import 'dart:async';
import 'dart:ffi';
import 'package:audioplayers/audio_cache.dart';
import 'package:flutter/material.dart';
import 'package:percent_indicator/percent_indicator.dart';
import 'package:pomodoroapp/model/menu_item.dart';
import 'package:pomodoroapp/model/pomodoro_status.dart';
import 'package:pomodoroapp/screens/report_screen.dart';
import 'package:pomodoroapp/screens/settings_screen.dart';
import 'package:pomodoroapp/utils/constants.dart';
import 'package:pomodoroapp/widget/custom_button.dart';
import 'package:pomodoroapp/widget/menu_items.dart';
import 'package:pomodoroapp/widget/progress_icons.dart';
class Home extends StatefulWidget {
//////////////////////// passed (changed) values //////////////////////
final pomodoroTimeChanged;
final shortBreakTimeChanged;
final longBreakTimeChanged;
Home(
{Key key,
this.pomodoroTimeChanged,
this.shortBreakTimeChanged,
this.longBreakTimeChanged})
: super(key: key);
#override
State<Home> createState() => _HomeState(
pomodoroTimeChanged, shortBreakTimeChanged, longBreakTimeChanged);
}
//////////////////////// main button labels ////////////////////////
const _btnTextStart = 'START';
const _btnTextResumePomodoro = 'RESUME';
const _btnTextResumeBreak = 'RESUME';
const _btnTextStartShortBreak = 'START';
const _btnTextStartLongBreak = 'START';
const _btnTextStartNewSet = 'START NEW SET';
const _btnTextPause = 'PAUSE';
const _btnTextReset = 'RESET';
#override
class _HomeState extends State<Home> {
//////////////////////// values //////////////////////
int pomodoroTime;
int shortBreakTime;
int longBreakTime;
//////////////////////// default times //////////////////////
int pomodoroTimeDefault = 5;
int shortBreakTimeDefault = 2;
int longBreakTimeDefault = 3;
int pomodoriPerSet = 4;
int pomodoroTimeChanged;
int shortBreakTimeChanged;
int longBreakTimeChanged;
_HomeState(this.pomodoroTimeChanged, this.shortBreakTimeChanged,
this.longBreakTimeChanged);
static AudioCache player = AudioCache();
int remainingTime = pomodoroTotalTime;
String mainBtnText = _btnTextStart;
PomodoroStatus pomodoroStatus = PomodoroStatus.pausedPomodoro;
Timer _timer;
int pomodoroNum = 0;
int setNum = 0;
//////////////////////// dispose, to avoid memory leak //////////////////////
#override
void dispose() {
_cancelTimer();
super.dispose();
}
/////////////////////// Update state function for changed value ///////////////////////
_updateStatepomodoroTime() {
setState(() {
remainingTime = pomodoroTime;
});
}
_updateStateShortBreakTime() {
setState(() {
remainingTime = shortBreakTime;
});
}
_updateStateLongBreakTime() {
setState(() {
remainingTime = longBreakTime;
});
}
#override
void initState() {
super.initState();
player.load('bell.mp3');
//////////////////// setting an initial value //////////////////////
if (pomodoroTimeChanged != null) {
pomodoroTime = pomodoroTimeChanged;
_updateStatepomodoroTime();
} else {
pomodoroTime = pomodoroTimeDefault;
}
if (shortBreakTimeChanged != null) {
shortBreakTime = shortBreakTimeChanged;
//_updateStateShortBreakTime();
_updateStatepomodoroTime();
} else {
shortBreakTime = shortBreakTimeDefault;
}
if (longBreakTimeChanged != null) {
longBreakTime = longBreakTimeChanged;
//_updateStateLongBreakTime();
_updateStatepomodoroTime();
} else {
longBreakTime = longBreakTimeDefault;
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
backgroundColor: Colors.grey[900],
appBar: PreferredSize(
preferredSize: Size.fromHeight(27.0),
child: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white, size: 10.0),
elevation: 0,
actions: [
PopupMenuButton<MenuItem>(
onSelected: (item) => onSelected(context, item),
itemBuilder: (context) =>
[...MenuItems.itemsFirst.map(buildItem).toList()],
)
],
),
),
body: Container(
width: double.infinity,
height: double.infinity,
decoration: const BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'https://firebasestorage.googleapis.com/v0/b/flutterbricks-1926c.appspot.com/o/images%2Fwidgets%2F1634411682152%2FScreen%20Shot%202021-10-16%20at%203.14.09%20PM.png?alt=media&token=ec556af9-6dff-4020-a530-2b1eec58dafe'),
fit: BoxFit.cover,
),
),
child: Center(
child: Column(
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularPercentIndicator(
radius: 220.0,
lineWidth: 15.0,
percent: _getPomodoroPercentage(),
circularStrokeCap: CircularStrokeCap.round,
center: Text(
_secondsToFormatedString(remainingTime),
style:
const TextStyle(fontSize: 40, color: Colors.white),
),
progressColor: statusColor[pomodoroStatus],
),
const SizedBox(
height: 12,
),
ProgressIcons(
total: pomodoriPerSet,
done: pomodoroNum - (setNum * pomodoriPerSet),
),
const SizedBox(
height: 12,
),
Text(
'#$setNum',
style: const TextStyle(fontSize: 15, color: Colors.grey),
),
const SizedBox(
height: 5,
),
Text(
statusDescription[pomodoroStatus],
style: const TextStyle(color: Colors.white),
),
const SizedBox(
height: 12,
),
const SizedBox(
height: 12,
),
CustomButton(
onTap: _mainButtonPressed,
text: mainBtnText,
),
CustomButton(
onTap: _resetButtonPressed,
text: _btnTextReset,
)
],
),
)
],
),
),
),
);
}
_secondsToFormatedString(int seconds) {
int roundedMinutes = seconds ~/ 60;
int remainingSeconds = seconds - (roundedMinutes * 60);
String remainingSecondsFormated;
if (remainingSeconds < 10) {
remainingSecondsFormated = '0$remainingSeconds';
} else {
remainingSecondsFormated = remainingSeconds.toString();
}
return '$roundedMinutes:$remainingSecondsFormated';
}
_getPomodoroPercentage() {
int totalTime;
switch (pomodoroStatus) {
case PomodoroStatus.runingPomodoro:
totalTime = pomodoroTime;
break;
case PomodoroStatus.pausedPomodoro:
totalTime = pomodoroTime;
break;
case PomodoroStatus.runningShortBreak:
totalTime = shortBreakTime;
break;
case PomodoroStatus.pausedShortBreak:
totalTime = shortBreakTime;
break;
case PomodoroStatus.runningLongBreak:
totalTime = longBreakTime;
break;
case PomodoroStatus.pausedLongBreak:
totalTime = longBreakTime;
break;
case PomodoroStatus.setFinished:
totalTime = pomodoroTime;
break;
}
double percentage = (totalTime - remainingTime) / totalTime;
return percentage;
}
_mainButtonPressed() {
switch (pomodoroStatus) {
case PomodoroStatus.pausedPomodoro:
_startPomodoroCountdown();
break;
case PomodoroStatus.runingPomodoro:
_pausePomodoroCountdown();
break;
case PomodoroStatus.runningShortBreak:
_pauseShortBreakCountdown();
break;
case PomodoroStatus.pausedShortBreak:
_startShortBreak();
break;
case PomodoroStatus.runningLongBreak:
_pauseLongBreakCountdown();
break;
case PomodoroStatus.pausedLongBreak:
_startLongBreak();
break;
case PomodoroStatus.setFinished:
setNum++;
_startPomodoroCountdown();
break;
}
}
_startPomodoroCountdown() {
pomodoroStatus = PomodoroStatus.runingPomodoro;
_cancelTimer();
if (_timer != null) {
_timer.cancel();
}
_timer = Timer.periodic(
Duration(seconds: 1),
(timer) => {
if (remainingTime > 0)
{
setState(() {
remainingTime--;
mainBtnText = _btnTextPause;
})
}
else
{
_playSound(),
pomodoroNum++,
_cancelTimer(),
if (pomodoroNum % pomodoriPerSet == 0)
{
pomodoroStatus = PomodoroStatus.pausedLongBreak,
setState(() {
remainingTime = longBreakTime;
mainBtnText = _btnTextStartLongBreak;
}),
}
else
{
pomodoroStatus = PomodoroStatus.pausedShortBreak,
setState(() {
remainingTime = shortBreakTime;
mainBtnText = _btnTextStartShortBreak;
}),
}
}
});
}
_startShortBreak() {
pomodoroStatus = PomodoroStatus.runningShortBreak;
setState(() {
mainBtnText = _btnTextPause;
});
_cancelTimer();
_timer = Timer.periodic(
Duration(seconds: 1),
(timer) => {
if (remainingTime > 0)
{
setState(() {
remainingTime--;
}),
}
else
{
_playSound(),
remainingTime = pomodoroTime,
_cancelTimer(),
pomodoroStatus = PomodoroStatus.pausedPomodoro,
setState(() {
mainBtnText = _btnTextStart;
}),
}
});
}
_startLongBreak() {
pomodoroStatus = PomodoroStatus.runningLongBreak;
setState(() {
mainBtnText = _btnTextPause;
});
_cancelTimer();
_timer = Timer.periodic(
Duration(seconds: 1),
(timer) => {
if (remainingTime > 0)
{
setState(() {
remainingTime--;
}),
}
else
{
_playSound(),
remainingTime = pomodoroTime,
_cancelTimer(),
pomodoroStatus = PomodoroStatus.setFinished,
setState(() {
mainBtnText = _btnTextStartNewSet;
}),
}
});
}
_pausePomodoroCountdown() {
pomodoroStatus = PomodoroStatus.pausedPomodoro;
_cancelTimer();
setState(() {
mainBtnText = _btnTextResumePomodoro;
});
}
_resetButtonPressed() {
pomodoroNum = 0;
setNum = 0;
_cancelTimer();
_stopCountdown();
}
_stopCountdown() {
pomodoroStatus = PomodoroStatus.pausedPomodoro;
setState(() {
mainBtnText = _btnTextStart;
remainingTime = pomodoroTime;
});
}
_pauseShortBreakCountdown() {
pomodoroStatus = PomodoroStatus.pausedShortBreak;
_pauseBreakCountdown();
}
_pauseLongBreakCountdown() {
pomodoroStatus = PomodoroStatus.pausedLongBreak;
_pauseBreakCountdown();
}
_pauseBreakCountdown() {
_cancelTimer();
setState(() {
mainBtnText = _btnTextResumeBreak;
});
}
_cancelTimer() {
if (_timer != null) {
_timer.cancel();
}
}
_playSound() {
player.play('bell.mp3');
}
PopupMenuItem<MenuItem> buildItem(MenuItem item) => PopupMenuItem<MenuItem>(
value: item,
child: Row(children: [
Icon(
item.icon,
color: Colors.black,
size: 20,
),
const SizedBox(
width: 12,
),
Text(item.text)
]),
);
void onSelected(BuildContext context, MenuItem item) {
switch (item) {
case MenuItems.itemSettings:
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => SettingsScreen()),
);
break;
case MenuItems.itemReport:
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => ReportScreen()),
);
break;
}
}
}
class PopUpMenu extends StatelessWidget {
final List<PopupMenuEntry> menuList;
final Widget icon;
const PopUpMenu({Key key, this.menuList, this.icon}) : super(key: key);
#override
Widget build(BuildContext context) {
return PopupMenuButton(
itemBuilder: (context) => menuList,
icon: icon,
);
}
}
Settings Screen
import 'package:flutter/material.dart';
import 'package:numberpicker/numberpicker.dart';
import 'package:pomodoroapp/screens/home_screen.dart';
class SettingsScreen extends StatefulWidget {
const SettingsScreen({Key key}) : super(key: key);
#override
_SettingsScreen createState() => _SettingsScreen();
}
class _SettingsScreen extends State<SettingsScreen>
with TickerProviderStateMixin {
// Switch states
int _workSessionValue = 25;
int _shortBreakValue = 5;
int _longBreakValue = 15;
NumberPicker integerNumberPicker;
////////////////////// values to pass //////////////////////
int pomodoroTimeToChanged;
int shortBreakTimeToChanged;
int longBreakTimeToChanged;
// Work Session
_handleWorkValueChange(num value) {
if (value != null) {
setState(() {
_workSessionValue = value;
});
}
}
_handleWorkValueChangedExternally(num value) {
if (value != null) {
setState(() {
_workSessionValue = value;
});
integerNumberPicker.animateInt(value);
}
print('Updated pomodoro value: $_workSessionValue ');
pomodoroTimeToChanged = value * 60;
}
// Short break
_handleShortBreakValueChange(num value) {
if (value != null) {
setState(() {
_shortBreakValue = value;
});
}
}
_handleShortBreakValueChangedExternally(num value) {
if (value != null) {
setState(() {
_shortBreakValue = value;
});
integerNumberPicker.animateInt(value);
}
print('Updated short break value: $_shortBreakValue ');
shortBreakTimeToChanged = value * 60;
}
// Long Break
_handleLongBreakValueChange(num value) {
if (value != null) {
setState(() {
_longBreakValue = value;
});
}
}
_handleLongBreakChangedExternally(num value) {
if (value != null) {
setState(() {
_longBreakValue = value;
});
integerNumberPicker.animateInt(value);
}
print('Updated Long break value: $_longBreakValue ');
longBreakTimeToChanged = value * 60;
}
// Animation
AnimationController animationController;
String get timerString {
Duration duration =
animationController.duration * animationController.value;
return '${duration.inMinutes.toString().padLeft(2, '0')}\n${(duration.inSeconds % 60).toString().padLeft(2, '0')}';
}
#override
void initState() {
super.initState();
animationController = AnimationController(
vsync: this, duration: const Duration(seconds: 1500));
}
//number pick values
#override
Widget build(BuildContext context) {
integerNumberPicker = NumberPicker.integer(
initialValue: _workSessionValue,
minValue: 1,
maxValue: 50,
onChanged: _handleWorkValueChange,
);
integerNumberPicker = NumberPicker.integer(
initialValue: _shortBreakValue,
minValue: 1,
maxValue: 50,
onChanged: _handleShortBreakValueChange,
);
integerNumberPicker = NumberPicker.integer(
initialValue: _longBreakValue,
minValue: 1,
maxValue: 50,
onChanged: _handleLongBreakValueChange,
);
//UI
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.chevron_left),
onPressed: () => {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => Home(
pomodoroTimeChanged: pomodoroTimeToChanged,
shortBreakTimeChanged: shortBreakTimeToChanged,
longBreakTimeChanged: longBreakTimeToChanged,
)))
},
),
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Text("Timer",
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.black,
fontSize: 32,
fontWeight: FontWeight.w700)),
const Divider(
thickness: 2,
color: Colors.black26,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
const Text(
"Pomodoro",
style: TextStyle(
color: Colors.black,
fontSize: 22,
fontWeight: FontWeight.w400),
),
Row(
children: <Widget>[
Container(
width: 30,
height: 30,
child: RawMaterialButton(
shape: const CircleBorder(),
onPressed: _showWorkSessionDialog,
fillColor: Colors.amber,
elevation: 0,
child: Text(
"$_workSessionValue",
style: const TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w500),
),
),
),
const Padding(
padding: EdgeInsets.all(5),
child: Text(
"min",
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.w500),
),
)
],
)
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
const Text(
"Short Break",
style: TextStyle(
color: Colors.black,
fontSize: 22,
fontWeight: FontWeight.w400),
),
Row(
children: <Widget>[
Container(
width: 30,
height: 30,
child: RawMaterialButton(
shape: CircleBorder(),
onPressed: _showShortBreakDialog,
fillColor: Colors.amber,
elevation: 0,
child: Text(
"$_shortBreakValue",
style: const TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w500),
),
),
),
const Padding(
padding: EdgeInsets.all(5),
child: Text(
"min",
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.w500),
),
)
],
)
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
const Text(
"Long Break",
style: TextStyle(
color: Colors.black,
fontSize: 22,
fontWeight: FontWeight.w400),
),
Row(
children: <Widget>[
Container(
width: 30,
height: 30,
child: RawMaterialButton(
shape: CircleBorder(),
onPressed: _showLongBreakDialog,
fillColor: Colors.amber,
elevation: 0,
child: Text(
"$_longBreakValue",
style: const TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w500),
),
),
),
const Padding(
padding: EdgeInsets.all(5),
child: Text(
"min",
style: TextStyle(
color: Colors.black,
fontSize: 18,
fontWeight: FontWeight.w500),
),
)
],
)
],
),
)
],
)
],
),
),
);
}
//dialog boxes
_showWorkSessionDialog() {
showDialog<int>(
context: context,
builder: (BuildContext context) {
return NumberPickerDialog.integer(
minValue: 0,
maxValue: 50,
initialIntegerValue: _workSessionValue,
title: const Text("Select a minute"),
);
},
).then(_handleWorkValueChangedExternally);
}
_showShortBreakDialog() {
showDialog<int>(
context: context,
builder: (BuildContext context) {
return NumberPickerDialog.integer(
minValue: 0,
maxValue: 50,
initialIntegerValue: _shortBreakValue,
title: const Text("Select a minute"),
);
},
).then(_handleShortBreakValueChangedExternally);
}
_showLongBreakDialog() {
showDialog<int>(
context: context,
builder: (BuildContext context) {
return NumberPickerDialog.integer(
minValue: 0,
maxValue: 50,
initialIntegerValue: _longBreakValue,
title: const Text("Select a minute"),
);
},
).then(_handleLongBreakChangedExternally);
}
}

Timer starts over when next_question selected

I'm making a quiz app using Flutter.
I have created a timer of 30 seconds which should start when a new question comes up.
It works fine and it restarts after the next question comes.
But when I click on "Next Question" without choosing an option, it restarts the timer.
I have created that button in such a way that you cannot go to the next question without choosing an option first.
Code:
#override
void initState() {
starttimer();
_questions = getData();
super.initState();
}
int index = 0;
int score = 0;
bool isPressed = false;
bool isAlreadySelected = false;
int timer = 30;
String showtimer = "30";
bool canceltimer = false;
void starttimer() async {
const onesec = Duration(seconds: 1);
Timer.periodic(onesec, (Timer t) {
setState(() {
if (timer < 1) {
t.cancel();
nextQuestion(index++);
} else if (canceltimer == true) {
t.cancel();
} else {
timer = timer - 1;
}
showtimer = timer.toString();
});
});
}
void nextQuestion(int questionLength) {
canceltimer = false;
timer = 30;
if (index == 19 || score == 12) {
showDialog(
context: context,
barrierDismissible: false,
builder: (ctx) => ResultBox(
result: score,
questionLength: questionLength,
));
} else {
if (isPressed) {
setState(() {
index++;
isPressed = false;
isAlreadySelected = false;
starttimer();
});
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: const Text('Please select any option'),
behavior: SnackBarBehavior.floating,
margin: EdgeInsets.symmetric(vertical: 20.0),
));
starttimer();
}
}
}
void checkAnswerAndUpdate(bool value) {
if (isAlreadySelected) {
return;
} else {
if (value == true) {
score++;
setState(() {
isPressed = true;
isAlreadySelected = false;
canceltimer = true;
});
} else if (value == false) {
setState(() {
isPressed = true;
isAlreadySelected = false;
canceltimer = true;
});
}
}
}
void startOver() {
setState(() {
Text('You have already attempted the LL Test');
});
}
#override
Widget build(BuildContext context) {
return FutureBuilder(
future: _questions as Future<List<Question>>,
builder: (ctx, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Center(
child: Text('${snapshot.error}'),
);
} else if (snapshot.hasData) {
var extractedData = snapshot.data as List<Question>;
return Scaffold(
backgroundColor: background,
appBar: AppBar(
title: const Text('LL Test'),
backgroundColor: background,
shadowColor: Colors.transparent,
actions: [
Padding(
padding: const EdgeInsets.all(18.0),
child: Text(
'Score: $score',
style: TextStyle(fontSize: 18.0),
),
)
],
),
body: Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
children: [
// Countdown(
// animation: StepTween(begin: limitTime, end: 0)
// .animate(_controller),
// ),
QuestionWidget(
question: extractedData[index].title,
indexAction: index,
totalQuestions: extractedData.length,
),
const Divider(
color: neutral,
),
const SizedBox(height: 25.0),
for (int i = 0;
i < extractedData[index].options.length;
i++)
GestureDetector(
onTap: () => checkAnswerAndUpdate(
extractedData[index].options.values.toList()[i]),
child: OptionCard(
option: extractedData[index].options.keys.toList()[i],
color: isPressed
? extractedData[index]
.options
.values
.toList()[i] ==
true
? correct
: incorrect
: neutral,
),
),
Expanded(
child: Container(
alignment: Alignment.topCenter,
child: Center(
child: Text(
showtimer,
style: TextStyle(
fontSize: 40.0,
fontWeight: FontWeight.w700,
fontFamily: 'Times New Roman',
color: neutral,
),
),
),
),
),
],
),
),
floatingActionButton: GestureDetector(
onTap: () => nextQuestion(extractedData.length),
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: NextButton(),
),
),
floatingActionButtonLocation:
FloatingActionButtonLocation.centerFloat,
);
}
} else {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
SizedBox(height: 20.0),
Text(
'Please Wait While Questions Are Loading..',
style: TextStyle(
backgroundColor: Color.fromARGB(255, 4, 82, 6),
color: neutral),
),
],
),
);
}
return const Center(
child: Text('NoData'),
);
},
);
}
}
Is it something wrong in my code? What should I do so that timer doesn't startover?
did you call the starttimer() inside else condition?
try to remove it.
} else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: const Text('Please select any option'),
behavior: SnackBarBehavior.floating,
margin: EdgeInsets.symmetric(vertical: 20.0),
));
// starttimer(); this call the function even its not selected yet
}

Adding next and previous buttons to a ListView in flutter

I was converting the following below ui to code.
I didn't find a suitable package for it, im stepper also didn't have the ability to customize in this way.
So I tried to use listView.builder.
Now I don't know how to add the next and previous buttons.
so that the number inside the scroll view scrolls like the picture below and is placed in the view area.
If you know a suitable package, introduce it.
my code:
FadingEdgeScrollView.fromScrollView(
gradientFractionOnEnd: 0.2,
gradientFractionOnStart: 0.15,
child: ListView.builder(
controller: _controller2,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int index) {
int one = index + 1;
int two = 0;
Color colorWhat(int q) {
Color color;
if (q == two) {
color = Color(0xff0AFF6C);
} else {
color = Colors.white;
}
return color;
}
double sizeOfCircle(int qq) {
int size;
if (qq == 0) {
size = 27;
} else {
size = 22;
}
return size.toDouble();
}
double sizeOfCircleText(int qqq) {
double size;
if (qqq < 10) {
size = 13.9;
} else {
size = 13.7;
}
return size;
}
return GestureDetector(
child: Row(
children: [
Container(
alignment: Alignment.center,
width: sizeOfCircle(index),
// height: sizeOfCircle(index),
// padding: EdgeInsets.all(sizeOfCircle(index)),
margin: const EdgeInsets.fromLTRB(
2, 0, 17, 0),
decoration: BoxDecoration(
color: colorWhat(index),
shape: BoxShape.circle,
boxShadow: const [
BoxShadow(
offset: Offset(0, 5),
blurRadius: 10.0,
spreadRadius: -7,
),
],
),
child: Text(
one.toString(),
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: sizeOfCircleText(index),
),
),
),
],
),
onTap: () =>
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text((index+1).toString()),
),
),
);
},
itemCount: 100,
),
),
first select a current index like this:
int currentPageIndex = 0;
and then on tap function. Write a code like this
for decrement...
if (currentPageIndex == 4) {
return;
}
setState(() {
currentPageIndex += 1;
});
for Increment...
if (currentPageIndex == 4) {
return;
}
setState(() {
currentPageIndex += 1;
});
Change your text...
Text(
'${index + 1}'
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: sizeOfCircleText(index),
),
),
and change your onTap function like this:
onTap: () {
setState(() {
currentPageIndex = index;
});
},

Dart - Tic Tac Toe examples of a method for one of the buttons in my game?

I am making a tic tac toe game using Dart and needed a little help implementing a button for my game. I am not too sure exactly how to start making a method for the buttons on the tic tac toe screen. How would I start with the first button method? I was going to use void _button0() {} but just not sure how to go about it for the first one since I'm new to Dart.
Also do I need to make 9 seperate methods for each of the buttons for the tic tac toe game?
import 'package:flutter/material.dart';
import 'dart:math';
class HomePage extends StatefulWidget {
#override
HomePageState createState() => HomePageState();
}
class HomePageState extends State<HomePage> {
// Constant Characters for each player
static const String humanPlayer = '1';
static const String computerPlayer = '2';
// Initial Text for Info Label
String text = "X's Turn";
// Constant for Board Size
static const boardSize = 9;
// Game Variables
var gameOver = false;
var win = 0;
var turn = 0;
var _mBoard = ["", "", "", "", "", "", "", "", ""];
var rnd = new Random(boardSize);
// Button Text Variables?
// Tic Tac Toe Game Code
void displayBoard() {
print("");
print(_mBoard[0] + " | " + _mBoard[1] + " | " + _mBoard[2]);
print("-----------");
print(_mBoard[3] + " | " + _mBoard[4] + " | " + _mBoard[5]);
print("-----------");
print(_mBoard[6] + " | " + _mBoard[7] + " | " + _mBoard[8]);
print("");
}
void checkGameOver(int win) {
print("");
if (win == 1) {
gameOver = true;
displayMessage("It's a tie.");
} else if (win == 2) {
gameOver = true;
displayMessage(humanPlayer + " wins!");
} else if (win == 3) {
gameOver = true;
displayMessage(computerPlayer + " wins!");
} else
displayMessage("There is a logic Problem!");
}
void displayMessage(String text) {
text = text;
print(text);
}
int checkWinner() {
// Check horizontal wins
for (int i = 0; i <= 6; i += 3) {
if (_mBoard[i] == (humanPlayer) &&
_mBoard[i + 1] == (humanPlayer) &&
_mBoard[i + 2] == (humanPlayer)) return 2;
if (_mBoard[i] == (computerPlayer) &&
_mBoard[i + 1] == (computerPlayer) &&
_mBoard[i + 2] == (computerPlayer)) return 3;
}
// Check vertical wins
for (int i = 0; i <= 2; i++) {
if (_mBoard[i] == (humanPlayer) &&
_mBoard[i + 3] == (humanPlayer) &&
_mBoard[i + 6] == (humanPlayer)) return 2;
if (_mBoard[i] == (computerPlayer) &&
_mBoard[i + 3] == (computerPlayer) &&
_mBoard[i + 6] == (computerPlayer)) return 3;
}
// Check for diagonal wins
if ((_mBoard[0] == (humanPlayer) &&
_mBoard[4] == (humanPlayer) &&
_mBoard[8] == (humanPlayer)) ||
(_mBoard[2] == (humanPlayer) &&
_mBoard[4] == (humanPlayer) &&
_mBoard[6] == (humanPlayer))) return 2;
if ((_mBoard[0] == (computerPlayer) &&
_mBoard[4] == (computerPlayer) &&
_mBoard[8] == (computerPlayer)) ||
(_mBoard[2] == (computerPlayer) &&
_mBoard[4] == (computerPlayer) &&
_mBoard[6] == (computerPlayer))) return 3;
for (int i = 0; i < boardSize; i++) {
// If we find a number, then no one has won yet
if (!(_mBoard[i] == (humanPlayer)) && !(_mBoard[i] == (computerPlayer)))
return 0;
}
// If we make it through the previous loop, all places are taken, so it's a tie*/
return 1;
}
void getComputerMove() {
int move;
// First see if there's a move O can make to win
for (int i = 0; i < boardSize; i++) {
if (_mBoard[i] != humanPlayer && _mBoard[i] != computerPlayer) {
String curr = _mBoard[i];
_mBoard[i] = computerPlayer;
if (checkWinner() == 3) {
print('Computer is moving to ${i + 1}');
return;
} else
_mBoard[i] = curr;
}
}
// See if there's a move O can make to block X from winning
for (int i = 0; i < boardSize; i++) {
if (_mBoard[i] != humanPlayer && _mBoard[i] != computerPlayer) {
String curr = _mBoard[i]; // Save the current number
_mBoard[i] = humanPlayer;
if (checkWinner() == 2) {
_mBoard[i] = computerPlayer;
print('Computer is moving to ${i + 1}');
return;
} else
_mBoard[i] = curr;
}
}
// Generate random move
do {
move = rnd.nextInt(boardSize);
} while (_mBoard[move] == humanPlayer || _mBoard[move] == computerPlayer);
print('Computer is moving to ${move + 1}');
_mBoard[move] = computerPlayer;
}
void _button0() {
}
//=====è
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Tic Tac Toe'),
leading: IconButton(
icon: Icon(
Icons.border_all,
semanticLabel: 'menu',
),
onPressed: () {},
),
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.new_releases),
onPressed: () {},
tooltip: 'New Game',
),
IconButton(
icon: new Icon(Icons.refresh),
onPressed: () {},
tooltip: 'Quit Game',
),
PopupMenuButton(itemBuilder: (BuildContext context) {
return [
PopupMenuItem(
child: new GestureDetector(
onTap: () {},
child: new Text("About",
style: TextStyle(
fontWeight: FontWeight.bold,
)),
),
),
PopupMenuItem(
child: new GestureDetector(
onTap: () {
// Some Method
},
child: new Text(
"Settings",
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
),
];
})
]),
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///
///
///
body: Center(
child:
Column(mainAxisAlignment: MainAxisAlignment.start, children: [
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Container(
height: 100,
width: 100,
margin: const EdgeInsets.all(10.0),
child: RaisedButton(
padding: const EdgeInsets.all(10.0),
onPressed: () {
},
child: Text(
"",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 80.0,
fontWeight: FontWeight.bold,
fontFamily: 'Roboto',
),
),
)),
Container(
height: 100,
width: 100,
margin: EdgeInsets.all(10.0),
child: RaisedButton(
padding: const EdgeInsets.all(10.0),
onPressed: () {
},
child: Text(
"",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 80,
fontWeight: FontWeight.bold,
fontFamily: "Roboto"),
),
)),
Container(
height: 100,
width: 100,
margin: EdgeInsets.all(10.0),
child: RaisedButton(
padding: const EdgeInsets.all(10.0),
onPressed: () {},
child: Text(
"",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 80,
fontWeight: FontWeight.bold,
fontFamily: "Roboto"),
),
)),
]),
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Container(
height: 100,
width: 100,
margin: const EdgeInsets.all(10.0),
child: RaisedButton(
padding: const EdgeInsets.all(10.0),
onPressed: () {},
child: Text(
"",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 80.0,
fontWeight: FontWeight.bold,
fontFamily: 'Roboto',
),
),
)),
Container(
height: 100,
width: 100,
margin: EdgeInsets.all(10.0),
child: RaisedButton(
padding: const EdgeInsets.all(10.0),
onPressed: () {},
child: Text(
"",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 80,
fontWeight: FontWeight.bold,
fontFamily: "Roboto"),
),
)),
Container(
height: 100,
width: 100,
margin: EdgeInsets.all(10.0),
child: RaisedButton(
padding: const EdgeInsets.all(10.0),
onPressed: () {},
child: Text(
"",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 80,
fontWeight: FontWeight.bold,
fontFamily: "Roboto"),
),
)),
]),
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Container(
height: 100,
width: 100,
margin: const EdgeInsets.all(10.0),
child: RaisedButton(
padding: const EdgeInsets.all(10.0),
onPressed: () {},
child: Text(
"",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 80.0,
fontWeight: FontWeight.bold,
fontFamily: 'Roboto',
),
),
)),
Container(
height: 100,
width: 100,
margin: EdgeInsets.all(10.0),
child: RaisedButton(
padding: const EdgeInsets.all(10.0),
onPressed: () {},
child: Text(
"",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 80,
fontWeight: FontWeight.bold,
fontFamily: "Roboto"),
),
)),
Container(
height: 100,
width: 100,
margin: EdgeInsets.all(10.0),
child: RaisedButton(
padding: const EdgeInsets.all(10.0),
onPressed: () {},
child: Text(
"",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 80,
fontWeight: FontWeight.bold,
fontFamily: "Roboto"),
),
)),
]),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 100,
width: 300,
margin: const EdgeInsets.all(10.0),
child: Text(
"X's Turn",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25.0,
fontWeight: FontWeight.bold,
fontFamily: 'Roboto',
),
),
)
],
),
Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Container(
height: 40,
width: 200,
margin: const EdgeInsets.all(10.0),
child: RaisedButton(
onPressed: () {},
child: Text(
"Reset App",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15.0,
fontWeight: FontWeight.bold,
fontFamily: 'Roboto',
),
),
))
]),
])));
}
}
You can copy paste run full code below
You can reference https://github.com/sbvkrishna/tictactoe-flutter
Step 1: You can create 9 Box(Button) with GridView.count and pass index to Box(Button) widget
GridView.count(
primary: false,
crossAxisCount: 3,
children: List.generate(9, (index) {
return Box(index);
}),
Step 2: You can put Button logic in onPressed and identify each Button with widget.index
class _BoxState extends State<Box> {
...
#override
Widget build(context) {
return MaterialButton(
padding: EdgeInsets.all(0),
child: Container(
decoration: BoxDecoration(
shape: BoxShape.rectangle,
border: new Border.all(color: Colors.blue)),
child: Center(
child: Text(
_board[widget.index].toUpperCase(),
style: TextStyle(
fontSize: 45,
fontWeight: FontWeight.bold,
),
),
)),
onPressed: () {
if (_board[widget.index] == '') {
if (vsBot == false) {
if (currentMoves % 2 == 0)
_board[widget.index] = 'x';
else
_board[widget.index] = 'o';
} else if (!loading) {
loading = true;
_board[widget.index] = 'o';
if (currentMoves >= 8) {
} else
_bestMove(_board);
//print(_board);
}
//print(vsBot);
pressed();
}
});
working demo
full code
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import 'package:flutter/gestures.dart';
import 'package:url_launcher/url_launcher.dart';
class About extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("About Me"),
),
body: aboutBody);
}
}
Widget get aboutBody {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [const Color(0xFFB3E5FC), const Color(0xFF2196F3)])),
padding: EdgeInsets.all(20),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
RichText(
text: TextSpan(children: [
TextSpan(
text: 'A Simple TicTacToe game made using ',
style: TextStyle(color: Colors.black, fontSize: 20),
),
TextSpan(
text: 'Flutter',
style: TextStyle(color: Colors.blue[900], fontSize: 20),
recognizer: TapGestureRecognizer()
..onTap = () {
launch('https://flutter.dev');
})
]),
),
Container(
height: 150,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text(
'Developed by Krishna S',
style: TextStyle(fontSize: 20),
),
Row(
children: <Widget>[
Icon(Icons.code),
InkWell(
child: Text(
' Github: sbvkrishna',
style: TextStyle(fontSize: 20, color: Colors.blue[900]),
),
onTap: () => {launch('https://github.com/sbvkrishna')},
)
],
),
Row(
children: <Widget>[
Icon(Icons.email),
Text(
' saladibalavijayakrishna#gmail.com',
style: TextStyle(fontSize: 18),
),
],
),
Text(''),
RichText(
text: TextSpan(children: [
TextSpan(
text: 'This Game\'s Source code is available at ',
style: TextStyle(color: Colors.black, fontSize: 20),
),
TextSpan(
text: 'Github',
style: TextStyle(color: Colors.blue[900], fontSize: 20),
recognizer: TapGestureRecognizer()
..onTap = () {
launch(
'https://github.com/sbvkrishna/tictactoe-flutter');
})
]),
),
],
),
)
],
));
}
int currentMoves = 0;
List<String> _board = ['', '', '', '', '', '', '', '', '']; //empty board
String status = '';
String winner = '';
var _gamePageState;
var _turnState;
var _context;
String _turn = 'First Move: X';
bool loading = false;
bool vsBot;
class GamePage extends StatefulWidget {
bool isBot;
GamePage(this.isBot) {
_resetGame();
vsBot = this.isBot;
if (vsBot) _turn = 'First Move: O';
}
#override
_GamePageState createState() => _GamePageState();
}
class _GamePageState extends State<GamePage> {
#override
Widget build(BuildContext context) {
_gamePageState = this;
return Scaffold(
appBar: AppBar(
//leading: Container(width: 0,height: 0,),
title: Text(vsBot ? 'Playing vs Bot' : 'Playing vs Friend'),
actions: <Widget>[
// IconButton(
// icon: Icon(Icons.settings_brightness),
// tooltip: 'Change Theme',
// onPressed: () {
// },
// ),
IconButton(
icon: Icon(Icons.info),
tooltip: 'About',
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return About();
}));
},
),
],
),
body: Container(
decoration: BoxDecoration(color: Colors.blue[200]),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[_BoxContainer(), Status()],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
awaitfn('Reset?', 'Want to reset the current game?', 'Go Back',
'Reset');
});
},
tooltip: 'Restart',
child: Icon(Icons.refresh),
),
);
}
}
class _BoxContainer extends StatelessWidget {
#override
Widget build(BuildContext context) {
_context = context;
return Container(
width: 300,
height: 300,
decoration: BoxDecoration(
color: Colors.white,
border: new Border.all(color: Colors.blue),
boxShadow: [
BoxShadow(
color: Colors.blue[100],
blurRadius: 20.0,
spreadRadius: 5.0,
offset: Offset(7.0, 7.0))
]),
child: Center(
child: GridView.count(
primary: false,
crossAxisCount: 3,
children: List.generate(9, (index) {
return Box(index);
}),
)));
}
}
class Box extends StatefulWidget {
final int index;
Box(this.index);
#override
_BoxState createState() => _BoxState();
}
class _BoxState extends State<Box> {
void pressed() {
print(currentMoves);
setState(() {
currentMoves++;
if (_checkGame()) {
awaitfnn();
} else if (currentMoves >= 9) {
awaitfn('It\'s a Draw', 'Want to try again?', 'Go Back', 'New Game');
}
_turnState.setState(() {
if (currentMoves % 2 == 0)
_turn = 'Turn: O';
else
_turn = 'Turn: X';
_gamePageState.setState(() {});
});
});
}
#override
Widget build(context) {
return MaterialButton(
padding: EdgeInsets.all(0),
child: Container(
decoration: BoxDecoration(
shape: BoxShape.rectangle,
border: new Border.all(color: Colors.blue)),
child: Center(
child: Text(
_board[widget.index].toUpperCase(),
style: TextStyle(
fontSize: 45,
fontWeight: FontWeight.bold,
),
),
)),
onPressed: () {
if (_board[widget.index] == '') {
if (vsBot == false) {
if (currentMoves % 2 == 0)
_board[widget.index] = 'x';
else
_board[widget.index] = 'o';
} else if (!loading) {
loading = true;
_board[widget.index] = 'o';
if (currentMoves >= 8) {
} else
_bestMove(_board);
//print(_board);
}
//print(vsBot);
pressed();
}
});
}
}
class Status extends StatefulWidget {
#override
_StatusState createState() => _StatusState();
}
class _StatusState extends State<Status> {
#override
Widget build(BuildContext context) {
_turnState = this;
return Card(
margin: EdgeInsets.all(40),
child: Container(
width: 220,
height: 60,
padding: EdgeInsets.fromLTRB(20, 10, 20, 10),
child: Text(
_turn,
style: TextStyle(fontSize: 30),
textAlign: TextAlign.center,
),
));
}
}
//-------------------------------------TicTacToe game fns ---------------------------
bool _checkGame() {
for (int i = 0; i < 9; i += 3) {
if (_board[i] != '' &&
_board[i] == _board[i + 1] &&
_board[i + 1] == _board[i + 2]) {
winner = _board[i];
return true;
}
}
for (int i = 0; i < 3; i++) {
if (_board[i] != '' &&
_board[i] == _board[i + 3] &&
_board[i + 3] == _board[i + 6]) {
winner = _board[i];
return true;
}
}
if (_board[0] != '' && (_board[0] == _board[4] && _board[4] == _board[8]) ||
(_board[2] != '' && _board[2] == _board[4] && _board[4] == _board[6])) {
winner = _board[4];
return true;
}
return false;
}
void _resetGame() {
currentMoves = 0;
status = '';
_board = ['', '', '', '', '', '', '', '', ''];
_turn = 'First Move: X';
loading = false;
}
//------------------------------ Alerts Dialog --------------------------------------
void awaitfnn() async {
bool result = await _showAlertBox(
_context, '$winner won!', 'Start a new Game?', 'Exit', 'New Game');
if (result) {
_gamePageState.setState(() {
_resetGame();
});
} else {
SystemChannels.platform.invokeMethod('SystemNavigator.pop');
}
}
Future<bool> _showAlertBox(BuildContext context, String title, String content,
String btn1, String btn2) async {
return showDialog<bool>(
context: context,
barrierDismissible: false,
builder: (BuildContext _context) => AlertDialog(
title: Text(title.toUpperCase()),
content: Text(content),
actions: <Widget>[
RaisedButton(
color: Colors.white,
child: Text(btn1),
onPressed: () {
Navigator.of(context).pop(false);
},
),
RaisedButton(
color: Colors.white,
child: Text(btn2),
onPressed: () {
Navigator.of(context).pop(true);
},
)
],
));
}
awaitfn(String title, String content, String btn1, String btn2) async {
bool result = await _showAlertBox(_context, title, content, btn1, btn2);
if (result) {
_gamePageState.setState(() {
_resetGame();
});
}
}
//------------------------------ MIN-MAX ------------------------------------------
int max(int a, int b) {
return a > b ? a : b;
}
int min(int a, int b) {
return a < b ? a : b;
}
String player = 'x', opponent = 'o';
bool isMovesLeft(List<String> _board) {
int i;
for (i = 0; i < 9; i++) {
if (_board[i] == '') return true;
}
return false;
}
int _eval(List<String> _board) {
for (int i = 0; i < 9; i += 3) {
if (_board[i] != '' &&
_board[i] == _board[i + 1] &&
_board[i + 1] == _board[i + 2]) {
winner = _board[i];
return (winner == player) ? 10 : -10;
}
}
for (int i = 0; i < 3; i++) {
if (_board[i] != '' &&
_board[i] == _board[i + 3] &&
_board[i + 3] == _board[i + 6]) {
winner = _board[i];
return (winner == player) ? 10 : -10;
}
}
if (_board[0] != '' && (_board[0] == _board[4] && _board[4] == _board[8]) ||
(_board[2] != '' && _board[2] == _board[4] && _board[4] == _board[6])) {
winner = _board[4];
return (winner == player) ? 10 : -10;
}
return 0;
}
int minmax(List<String> _board, int depth, bool isMax) {
int score = _eval(_board);
//print(score);
int best = 0, i;
if (score == 10 || score == -10) return score;
if (!isMovesLeft(_board)) return 0;
if (isMax) {
best = -1000;
for (i = 0; i < 9; i++) {
if (_board[i] == '') {
_board[i] = player;
best = max(best, minmax(_board, depth + 1, !isMax));
_board[i] = '';
}
}
return best;
} else {
best = 1000;
for (i = 0; i < 9; i++) {
if (_board[i] == '') {
_board[i] = opponent;
best = min(best, minmax(_board, depth + 1, !isMax));
_board[i] = '';
}
}
//print(best);
return best;
}
}
int _bestMove(List<String> _board) {
int bestMove = -1000, moveVal;
int i, bi;
for (i = 0; i < 9; i++) {
if (_board[i] == '') {
moveVal = -1000;
_board[i] = player;
moveVal = minmax(_board, 0, false);
_board[i] = '';
if (moveVal > bestMove) {
bestMove = moveVal;
bi = i;
}
}
}
_board[bi] = player;
_gamePageState.setState(() {});
loading = false;
_turnState.setState(() {
_turn = 'Turn: X';
currentMoves++;
});
return bestMove;
}
//---------------------------------------- API ----------------------------------
// Future gameAPI() async {
// var url = 'http://perfecttictactoe.herokuapp.com/api/v2/play';
// Map data = {
// "player_piece": "o",
// "opponent_piece": "x",
// "board": [
// {"id": "top-left", "value": _board[0]},
// {"id": "top-center", "value": _board[1]},
// {"id": "top-right", "value": _board[2]},
// {"id": "middle-left", "value": _board[3]},
// {"id": "middle-center", "value": _board[4]},
// {"id": "middle-right", "value": _board[5]},
// {"id": "bottom-left", "value": _board[6]},
// {"id": "bottom-center", "value": _board[7]},
// {"id": "bottom-right", "value": _board[8]}
// ]
// };
// var res = await http.post(url, body: json.encode(data));
// if (res.statusCode == 200) {
// var resBody = json.decode(res.body);
// if (resBody['status'] == 'success') {
// var newBoard = resBody['data'];
// if (newBoard['status'] == 'win') {
// winner = newBoard['winner'];
// awaitfnn();
// } else if (newBoard['status'] == 'draw') {
// awaitfn('It"s a Draw', 'Want to try again?', 'Go Back', 'New Game');
// }
// int i = 0;
// newBoard['board'].forEach((box) => {_board[i++] = box['value']});
// }
// _gamePageState.setState(() {});
// loading = false;
// _turnState.setState(() {
// _turn = 'Turn: X';
// currentMoves++;
// });
// }
// }
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("TicTacToe"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.info),
tooltip: 'About',
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return About();
}));
},
),
],
),
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [const Color(0xFFB3E5FC), const Color(0xFF2196F3)])),
padding: EdgeInsets.all(5),
child: Column(
children: <Widget>[
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.close,
size: 140,
color: Colors.lightBlue[800],
),
Icon(
Icons.radio_button_unchecked,
size: 108,
color: Colors.lightBlue[800],
)
],
),
),
Center(
child: Container(
width: 310,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
RaisedButton(
padding: EdgeInsets.fromLTRB(10, 5, 10, 6),
child: Container(
width: 130,
child: Center(
child: Text(
'vs Bot',
style: TextStyle(
color: Colors.lightBlue[800], fontSize: 30),
),
)),
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) {
return GamePage(true);
}));
},
),
RaisedButton(
padding: EdgeInsets.fromLTRB(10, 5, 10, 6),
child: Container(
width: 130,
child: Center(
child: Text(
'vs Friend',
style: TextStyle(
color: Colors.lightBlue[800], fontSize: 30),
),
)),
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) {
return GamePage(false);
}));
},
),
],
),
),
)
],
)),
);
}
}
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'TicTacToe',
theme: ThemeData(
primarySwatch: Colors.blue,
brightness: Brightness.light,
//fontFamily: ''
),
home: HomePage(),
);
}
}

ListView builder don't change in the required time

I have search method who it can detect element form map and put theme in List variable where my List view builder takes his elements from.
the problem when I insert my word in Text Filed , list view builder doesn't change her statement until I close the keyboard and then I can see the change.
I want to see elements who I search currently
this my code :
_showDialog(){
var searchList = [];
int _manyOfWidgetShow = 0;
double heightOfListView = 0;
double higNumber(){
double _number;
if(_manyOfWidgetShow == 0){
_number = 0.25;
}
else if(_manyOfWidgetShow == 1){
_number = 0.3;
}else if(_manyOfWidgetShow == 2){
_number = 0.5;
}else if(_manyOfWidgetShow == 3){
_number = 0.6;
}
return _number;
}
void _showSearchReturn(String query){
List _items = [];
if(query.isNotEmpty){
testList.forEach( (element){
if(element["name"].toString().toLowerCase().startsWith(query) && _items.length < 3){
_items.add(element);
}
else if(query.length >= 2 && element["name"].toString().toLowerCase().contains(query) && _items.length < 3){
_items.add(element);
}
}
);
setState(() {
_manyOfWidgetShow = _items.length;
if(_manyOfWidgetShow != 0) {
heightOfListView = _manyOfWidgetShow * 50.0;
}else{
heightOfListView = 0;
}
searchList.clear();
searchList.addAll(_items);
});
}else{
setState(() {
_manyOfWidgetShow = _items.length;
if(_manyOfWidgetShow != 0){
heightOfListView = _manyOfWidgetShow * 50.0;
}else{
heightOfListView = 0;
}
searchList.clear();
});
}
}
showDialog(
context: context,
builder: (BuildContext context){
var _size = MediaQuery.of(context).size;
return Container(
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30)
),
child: Container(
height: _size.height * higNumber(),
child: Column(
children: <Widget>[
Card(
margin: EdgeInsets.only(top:20,bottom: 15),
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)
),
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.only(top: 15,bottom: 18),
child: TextField(
onChanged: (value){
_showSearchReturn(value);
},
scrollPadding: EdgeInsets.all(20),
autocorrect: false,
decoration: InputDecoration.collapsed(
hintText: "Movie name",
),
style: TextStyle(
fontSize: 20
),
strutStyle: StrutStyle(
fontWeight: FontWeight.bold,
height: 1.5
),
controller: searchText ,
cursorWidth: 2,
cursorColor: Color(0xff54C4A2),
textAlign: TextAlign.center,
),
)
),
Container(
height: heightOfListView,
child: ListView.builder(
itemCount: searchList.length,
shrinkWrap: true,
itemBuilder:(context,index){
return ItemInfo(searchList[index]["name"],searchList[index]["id"]);
}
)
),
Expanded(
child: Container(
alignment: Alignment.bottomLeft,
child: IconButton(icon: Icon(Icons.arrow_back_ios,color: Colors.black54,),
onPressed: (){
},
),
)
)
],
),
),
)
);
}
);
}