Flutter - change button color while running
I am writing a trivia app in Flutter.
I want the button's color to change after selecting the answer according to the correctness of it and wait a few seconds before displaying the next question.
I tried to call setState with the colors and sleep but it only causes the diaply to delay a bit and then show the next question without changing the colors at all.
Any suggestions ?
Color getColor(int num)
{
if(!_pressed)
{
return Colors.black;
}
return question.correct == num ? Colors.green : (_colored != num ? Colors.black : Colors.red);
}
void onPressed(int btn) {
stopSpeech();
setState(() {
_colored = btn;
_pressed = true;
if (question.correct == btn)
{
finalScore++;
}
sleep(new Duration(seconds:1));
updateQuestion();
});
}
RaisedButton buildButton(int num)
{
var btn = new RaisedButton(
color: getColor(num),
onPressed: () => onPressed(num),
child: new Text(
textForButton(num),
style:
new TextStyle(fontSize: 30.0, color: Colors.white),
),
return btn;
}
@override
Widget build(BuildContext context)
{
return new WillPopScope(
onWillPop: () async => false,
child: Scaffold(
body: new Container(
margin: const EdgeInsets.all(10.0),
alignment: Alignment.topCenter,
child: new Column(
children: <Widget>[
new Padding(padding: EdgeInsets.all(20.0)),
new Container(
alignment: Alignment.centerRight,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Text(
"${Strings.Score} $finalScore/${questions.length}",
style: new TextStyle(fontSize: 22.0),
),
new Text("${Strings.Question} ${questionNumber + 1}",
style: new TextStyle(fontSize: 22.0),
)
],
),
),
new Padding(padding: EdgeInsets.all(10.0)),
new Padding(padding: EdgeInsets.all(10.0)),
new Text(
question.question,
textAlign: TextAlign.center,
style: new TextStyle(
fontSize: 40.0,
fontWeight: FontWeight.bold,
),
),
new Padding(padding: EdgeInsets.all(10.0)),
new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
buildButton(1),
new Padding(padding: EdgeInsets.all(10.0)),
buildButton(2),
new Padding(padding: EdgeInsets.all(10.0)),
buildButton(3),
new Padding(padding: EdgeInsets.all(10.0)),
buildButton(4),
],
),
new Padding(padding: EdgeInsets.all(15.0)),
new Container(
alignment: Alignment.center,
child: new MaterialButton(
minWidth: 240.0,
height: 30.0,
color: Colors.blueGrey,
onPressed: resetQuiz,
child: new Text(
Strings.Quit,
style: new TextStyle(
fontSize: 18.0, color: Colors.white),
))),
],
),
),
));
}
add a comment |
I am writing a trivia app in Flutter.
I want the button's color to change after selecting the answer according to the correctness of it and wait a few seconds before displaying the next question.
I tried to call setState with the colors and sleep but it only causes the diaply to delay a bit and then show the next question without changing the colors at all.
Any suggestions ?
Color getColor(int num)
{
if(!_pressed)
{
return Colors.black;
}
return question.correct == num ? Colors.green : (_colored != num ? Colors.black : Colors.red);
}
void onPressed(int btn) {
stopSpeech();
setState(() {
_colored = btn;
_pressed = true;
if (question.correct == btn)
{
finalScore++;
}
sleep(new Duration(seconds:1));
updateQuestion();
});
}
RaisedButton buildButton(int num)
{
var btn = new RaisedButton(
color: getColor(num),
onPressed: () => onPressed(num),
child: new Text(
textForButton(num),
style:
new TextStyle(fontSize: 30.0, color: Colors.white),
),
return btn;
}
@override
Widget build(BuildContext context)
{
return new WillPopScope(
onWillPop: () async => false,
child: Scaffold(
body: new Container(
margin: const EdgeInsets.all(10.0),
alignment: Alignment.topCenter,
child: new Column(
children: <Widget>[
new Padding(padding: EdgeInsets.all(20.0)),
new Container(
alignment: Alignment.centerRight,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Text(
"${Strings.Score} $finalScore/${questions.length}",
style: new TextStyle(fontSize: 22.0),
),
new Text("${Strings.Question} ${questionNumber + 1}",
style: new TextStyle(fontSize: 22.0),
)
],
),
),
new Padding(padding: EdgeInsets.all(10.0)),
new Padding(padding: EdgeInsets.all(10.0)),
new Text(
question.question,
textAlign: TextAlign.center,
style: new TextStyle(
fontSize: 40.0,
fontWeight: FontWeight.bold,
),
),
new Padding(padding: EdgeInsets.all(10.0)),
new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
buildButton(1),
new Padding(padding: EdgeInsets.all(10.0)),
buildButton(2),
new Padding(padding: EdgeInsets.all(10.0)),
buildButton(3),
new Padding(padding: EdgeInsets.all(10.0)),
buildButton(4),
],
),
new Padding(padding: EdgeInsets.all(15.0)),
new Container(
alignment: Alignment.center,
child: new MaterialButton(
minWidth: 240.0,
height: 30.0,
color: Colors.blueGrey,
onPressed: resetQuiz,
child: new Text(
Strings.Quit,
style: new TextStyle(
fontSize: 18.0, color: Colors.white),
))),
],
),
),
));
}
Could you post your widget tree code and your stateful widget classes?
– shadowsheep
Dec 28 '18 at 9:47
I edited the question if it helps
– Blondy314
Dec 28 '18 at 10:44
add a comment |
I am writing a trivia app in Flutter.
I want the button's color to change after selecting the answer according to the correctness of it and wait a few seconds before displaying the next question.
I tried to call setState with the colors and sleep but it only causes the diaply to delay a bit and then show the next question without changing the colors at all.
Any suggestions ?
Color getColor(int num)
{
if(!_pressed)
{
return Colors.black;
}
return question.correct == num ? Colors.green : (_colored != num ? Colors.black : Colors.red);
}
void onPressed(int btn) {
stopSpeech();
setState(() {
_colored = btn;
_pressed = true;
if (question.correct == btn)
{
finalScore++;
}
sleep(new Duration(seconds:1));
updateQuestion();
});
}
RaisedButton buildButton(int num)
{
var btn = new RaisedButton(
color: getColor(num),
onPressed: () => onPressed(num),
child: new Text(
textForButton(num),
style:
new TextStyle(fontSize: 30.0, color: Colors.white),
),
return btn;
}
@override
Widget build(BuildContext context)
{
return new WillPopScope(
onWillPop: () async => false,
child: Scaffold(
body: new Container(
margin: const EdgeInsets.all(10.0),
alignment: Alignment.topCenter,
child: new Column(
children: <Widget>[
new Padding(padding: EdgeInsets.all(20.0)),
new Container(
alignment: Alignment.centerRight,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Text(
"${Strings.Score} $finalScore/${questions.length}",
style: new TextStyle(fontSize: 22.0),
),
new Text("${Strings.Question} ${questionNumber + 1}",
style: new TextStyle(fontSize: 22.0),
)
],
),
),
new Padding(padding: EdgeInsets.all(10.0)),
new Padding(padding: EdgeInsets.all(10.0)),
new Text(
question.question,
textAlign: TextAlign.center,
style: new TextStyle(
fontSize: 40.0,
fontWeight: FontWeight.bold,
),
),
new Padding(padding: EdgeInsets.all(10.0)),
new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
buildButton(1),
new Padding(padding: EdgeInsets.all(10.0)),
buildButton(2),
new Padding(padding: EdgeInsets.all(10.0)),
buildButton(3),
new Padding(padding: EdgeInsets.all(10.0)),
buildButton(4),
],
),
new Padding(padding: EdgeInsets.all(15.0)),
new Container(
alignment: Alignment.center,
child: new MaterialButton(
minWidth: 240.0,
height: 30.0,
color: Colors.blueGrey,
onPressed: resetQuiz,
child: new Text(
Strings.Quit,
style: new TextStyle(
fontSize: 18.0, color: Colors.white),
))),
],
),
),
));
}
I am writing a trivia app in Flutter.
I want the button's color to change after selecting the answer according to the correctness of it and wait a few seconds before displaying the next question.
I tried to call setState with the colors and sleep but it only causes the diaply to delay a bit and then show the next question without changing the colors at all.
Any suggestions ?
Color getColor(int num)
{
if(!_pressed)
{
return Colors.black;
}
return question.correct == num ? Colors.green : (_colored != num ? Colors.black : Colors.red);
}
void onPressed(int btn) {
stopSpeech();
setState(() {
_colored = btn;
_pressed = true;
if (question.correct == btn)
{
finalScore++;
}
sleep(new Duration(seconds:1));
updateQuestion();
});
}
RaisedButton buildButton(int num)
{
var btn = new RaisedButton(
color: getColor(num),
onPressed: () => onPressed(num),
child: new Text(
textForButton(num),
style:
new TextStyle(fontSize: 30.0, color: Colors.white),
),
return btn;
}
@override
Widget build(BuildContext context)
{
return new WillPopScope(
onWillPop: () async => false,
child: Scaffold(
body: new Container(
margin: const EdgeInsets.all(10.0),
alignment: Alignment.topCenter,
child: new Column(
children: <Widget>[
new Padding(padding: EdgeInsets.all(20.0)),
new Container(
alignment: Alignment.centerRight,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Text(
"${Strings.Score} $finalScore/${questions.length}",
style: new TextStyle(fontSize: 22.0),
),
new Text("${Strings.Question} ${questionNumber + 1}",
style: new TextStyle(fontSize: 22.0),
)
],
),
),
new Padding(padding: EdgeInsets.all(10.0)),
new Padding(padding: EdgeInsets.all(10.0)),
new Text(
question.question,
textAlign: TextAlign.center,
style: new TextStyle(
fontSize: 40.0,
fontWeight: FontWeight.bold,
),
),
new Padding(padding: EdgeInsets.all(10.0)),
new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
buildButton(1),
new Padding(padding: EdgeInsets.all(10.0)),
buildButton(2),
new Padding(padding: EdgeInsets.all(10.0)),
buildButton(3),
new Padding(padding: EdgeInsets.all(10.0)),
buildButton(4),
],
),
new Padding(padding: EdgeInsets.all(15.0)),
new Container(
alignment: Alignment.center,
child: new MaterialButton(
minWidth: 240.0,
height: 30.0,
color: Colors.blueGrey,
onPressed: resetQuiz,
child: new Text(
Strings.Quit,
style: new TextStyle(
fontSize: 18.0, color: Colors.white),
))),
],
),
),
));
}
edited Dec 28 '18 at 10:44
Blondy314
asked Dec 28 '18 at 9:33
Blondy314Blondy314
366421
366421
Could you post your widget tree code and your stateful widget classes?
– shadowsheep
Dec 28 '18 at 9:47
I edited the question if it helps
– Blondy314
Dec 28 '18 at 10:44
add a comment |
Could you post your widget tree code and your stateful widget classes?
– shadowsheep
Dec 28 '18 at 9:47
I edited the question if it helps
– Blondy314
Dec 28 '18 at 10:44
Could you post your widget tree code and your stateful widget classes?
– shadowsheep
Dec 28 '18 at 9:47
Could you post your widget tree code and your stateful widget classes?
– shadowsheep
Dec 28 '18 at 9:47
I edited the question if it helps
– Blondy314
Dec 28 '18 at 10:44
I edited the question if it helps
– Blondy314
Dec 28 '18 at 10:44
add a comment |
1 Answer
1
active
oldest
votes
Using sleep doesn't work in Flutter. The UI doesn't get a chance to re-render between updating the color and final score and updating the question because it is busy sleeping. Put another way, the UI only updates after returning from setState. As there is only one call to setState the UI only updates once (combining the color change and question change in one).
Refactor onPressed so that it just updates the colors but schedules the question change in the future.
void onPressed(int btn) {
stopSpeech();
setState(() {
_colored = btn;
_pressed = true;
if (question.correct == btn) {
finalScore++;
}
});
Future<void>.delayed(Duration(seconds: 1), () => updateQuestion());
}
Make sure that updateQuestion also calls setState so that its changes trigger the necessary UI build.
That did the trick, thanks :)
– Blondy314
Dec 28 '18 at 16:03
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53956350%2fflutter-change-button-color-while-running%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Using sleep doesn't work in Flutter. The UI doesn't get a chance to re-render between updating the color and final score and updating the question because it is busy sleeping. Put another way, the UI only updates after returning from setState. As there is only one call to setState the UI only updates once (combining the color change and question change in one).
Refactor onPressed so that it just updates the colors but schedules the question change in the future.
void onPressed(int btn) {
stopSpeech();
setState(() {
_colored = btn;
_pressed = true;
if (question.correct == btn) {
finalScore++;
}
});
Future<void>.delayed(Duration(seconds: 1), () => updateQuestion());
}
Make sure that updateQuestion also calls setState so that its changes trigger the necessary UI build.
That did the trick, thanks :)
– Blondy314
Dec 28 '18 at 16:03
add a comment |
Using sleep doesn't work in Flutter. The UI doesn't get a chance to re-render between updating the color and final score and updating the question because it is busy sleeping. Put another way, the UI only updates after returning from setState. As there is only one call to setState the UI only updates once (combining the color change and question change in one).
Refactor onPressed so that it just updates the colors but schedules the question change in the future.
void onPressed(int btn) {
stopSpeech();
setState(() {
_colored = btn;
_pressed = true;
if (question.correct == btn) {
finalScore++;
}
});
Future<void>.delayed(Duration(seconds: 1), () => updateQuestion());
}
Make sure that updateQuestion also calls setState so that its changes trigger the necessary UI build.
That did the trick, thanks :)
– Blondy314
Dec 28 '18 at 16:03
add a comment |
Using sleep doesn't work in Flutter. The UI doesn't get a chance to re-render between updating the color and final score and updating the question because it is busy sleeping. Put another way, the UI only updates after returning from setState. As there is only one call to setState the UI only updates once (combining the color change and question change in one).
Refactor onPressed so that it just updates the colors but schedules the question change in the future.
void onPressed(int btn) {
stopSpeech();
setState(() {
_colored = btn;
_pressed = true;
if (question.correct == btn) {
finalScore++;
}
});
Future<void>.delayed(Duration(seconds: 1), () => updateQuestion());
}
Make sure that updateQuestion also calls setState so that its changes trigger the necessary UI build.
Using sleep doesn't work in Flutter. The UI doesn't get a chance to re-render between updating the color and final score and updating the question because it is busy sleeping. Put another way, the UI only updates after returning from setState. As there is only one call to setState the UI only updates once (combining the color change and question change in one).
Refactor onPressed so that it just updates the colors but schedules the question change in the future.
void onPressed(int btn) {
stopSpeech();
setState(() {
_colored = btn;
_pressed = true;
if (question.correct == btn) {
finalScore++;
}
});
Future<void>.delayed(Duration(seconds: 1), () => updateQuestion());
}
Make sure that updateQuestion also calls setState so that its changes trigger the necessary UI build.
answered Dec 28 '18 at 13:51
Richard HeapRichard Heap
5,6042515
5,6042515
That did the trick, thanks :)
– Blondy314
Dec 28 '18 at 16:03
add a comment |
That did the trick, thanks :)
– Blondy314
Dec 28 '18 at 16:03
That did the trick, thanks :)
– Blondy314
Dec 28 '18 at 16:03
That did the trick, thanks :)
– Blondy314
Dec 28 '18 at 16:03
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53956350%2fflutter-change-button-color-while-running%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Could you post your widget tree code and your stateful widget classes?
– shadowsheep
Dec 28 '18 at 9:47
I edited the question if it helps
– Blondy314
Dec 28 '18 at 10:44