My code is basic as my question:
Why I am not able to add the answers after click on Radio Button
and also print
the answer on the console with this code?
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyQuestion(),
);
}
}
class MyQuestion extends StatefulWidget {
const MyQuestion({super.key});
@override
State<MyQuestion> createState() => _MyQuestionState();
}
class _MyQuestionState extends State<MyQuestion> {
final List<String> selectedAnswers = [];
void chooseAnswer(String answer) {
setState(() {
selectedAnswers.add(answer);
});
}
@override
Widget build(BuildContext context) {
return const Scaffold(
body: Padding(
padding: EdgeInsets.all(8.0),
child: FirstScreen(),
),
);
}
}
class FirstScreen extends StatefulWidget {
const FirstScreen({super.key});
@override
State<FirstScreen> createState() => _FirstScreenState();
}
class _FirstScreenState extends State<FirstScreen> {
int selectedOption = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(
'Seja Bem-Vindo (a) ao QuestionĂ¡rio TAS-20',
style: TextStyle(
color: Colors.amber,
fontSize: 16,
),
),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const MyQuestion(),
),
);
},
),
),
body: Padding(
padding: const EdgeInsets.all(6.0),
child: ListView(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Radio(
value: 1,
groupValue: selectedOption,
onChanged: (value) {
setState(() {
selectedOption = value as int;
_MyQuestionState().chooseAnswer(value as String);
});
},
),
Radio(
value: 2,
groupValue: selectedOption,
onChanged: (value) {
setState(() {
selectedOption = value as int;
_MyQuestionState().chooseAnswer(value as String);
});
},
),
Radio(
value: 3,
groupValue: selectedOption,
onChanged: (value) {
setState(() {
selectedOption = value as int;
_MyQuestionState().chooseAnswer(value as String);
});
},
),
Radio(
value: 4,
groupValue: selectedOption,
onChanged: (value) {
setState(() {
selectedOption = value as int;
_MyQuestionState().chooseAnswer(value as String);
});
},
),
],
),
const Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text('Answer 1'),
Text('Answer 2'),
Text('Answer 3'),
Text('Answer 4')
],
),
ElevatedButton(
onPressed: () {},
child: const Text('Next'),
),
],
),
),
);
}
}
I think my main problem is how to use this chunk of code into FirstScreen statefull Widget:
final List<String> selectedAnswers = [];
void chooseAnswer(String answer) {
setState(() {
selectedAnswers.add(answer);
});
}
I tried to include _MyQuestionState().chooseAnswer(value as String);
at onChanged
argument but its not working.
Also at the same time I answer I am not able to include as a print on the console the answer that the user chosed.
2
Answers
There are several things that need to be fixed:
int
to aString
by using the type castas String
. You should use thetoString
method instead, so changevalue as String
tovalue.toString()
._MyQuestionState().chooseAnswer
, you’re actually creating a new instance of_MyQuestionState()
, and not controlling the existing state. If you want to be able to call thechooseAnswer
fromFirstScreen
, you should pass the callback in_MyQuestionState
like this:In
FirstScreen
, add thechooseAnswer
parameter:After that, change the call of
_MyQuestionState().chooseAnswer
towidget.chooseAnswer
. Additionally, you don’t need to put this call insidesetState
, so youronChanged
callback should look like this:FULL CODE
First off, if you run your code, you’ll see an erorr:
This is because in your code, you are doing:
value is an
int
, not aString
, as I have commentedTo fix the issue just call
.toString
:that fixes problem 1
But then, if you run your code again, you’ll encounter another problem once selecting a checkbox:
This is because the Widget is not yet mounted/created. So, to solve the issue, you can use a short deelay:
Also, you should remove the
setState
fromchoooseAnswer
and call it in the
onChanged
.Your complete working code should look like: