【发布时间】:2021-12-29 10:52:54
【问题描述】:
我正在使用 Flutter-Dart-SQLite 开发一个测验应用程序。在这里,我使用 RadioListTile 来实现单选按钮功能。我将数组中的文本值传递给这个StatefulWidget。
这是我正在使用的代码,
import 'package:flutter/material.dart';
import 'package:get/get_state_manager/get_state_manager.dart';
import 'package:loginform_validation_demo/QuizApp/controllers/question_controller.dart';
import 'package:loginform_validation_demo/resource-file/constants.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/src/material/radio_list_tile.dart';
class OptionRadio extends StatefulWidget {
final String text;
final int index;
final VoidCallback press;
const OptionRadio({
Key key,
this.text,
this.index,
this.press,
}) : super();
@override
OptionRadioPage createState() =>
OptionRadioPage(this.text, this.index, this.press);
}
class OptionRadioPage extends State<OptionRadio> {
final String text;
int index;
final VoidCallback press;
QuestionController controllerCopy =QuestionController();
int id = 1;
int selectedButton = null;
bool _isButtonDisabled;
OptionRadioPage(this.text, this.index, this.press);
@override
void initState() {
_isButtonDisabled = false;
}
int _selected = null;
@override
Widget build(BuildContext context) {
return GetBuilder<QuestionController>(
init: QuestionController(),
builder: (qnController) {
Color getTheRightColor() {
if (qnController.isAnswered) {
if (index == qnController.selectedAns &&
qnController.selectedAns == qnController.correctAns) {
return kBlackColor;
} else if (index == qnController.selectedAns &&
qnController.selectedAns != qnController.correctAns) {
return kBlackColor;
}
}
return kBlackColor;
}
return InkWell(
onTap: press,
child: Container(
child: Row(
children: <Widget>[
Expanded(
child: Container(
// height: 60.0,
child: Theme(
data: Theme.of(context).copyWith(
unselectedWidgetColor: Colors.grey,
disabledColor: Colors.blue),
child: Column(children:
[
RadioListTile(
title: Text(
"${index + 1}. $text",
style: TextStyle(
color: getTheRightColor(), fontSize: 16),
softWrap: true,
),
/*Here the selectedButton which is null initially takes place of value after onChanged. Now, I need to clear the selected button when other button is clicked */
groupValue: selectedButton,
value: index,
activeColor: Colors.green,
onChanged:
(val) async {
debugPrint(
'Radio button is clicked onChanged $val');
setState(() {
debugPrint('Radio button setState $val');
selectedButton = val;
debugPrint('Radio button is clicked onChanged $index');
});
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setInt('intValue', val);
},
toggleable: true,
),
]
),
)),
),
],
),
),
);
});
}
@override
State<StatefulWidget> createState() {
throw UnimplementedError();
}
}
这里的 selectedButton 最初为 null 代替 onChanged 之后的组值的值。现在,我需要在单击另一个按钮时清除选定的按钮。
我猜我在组值部分做错了。
我使用 OptionRadio 的部分,
class QuestionCardWidgetRadio extends StatelessWidget {
OptionRadio optionRadio = OptionRadio();
QuestionCardWidgetRadio({
Key key,
this.note,
this.index,
this.questionLength,
}) : super(key: key);
final BlazorQuiz note;
final int index;
final int questionLength;
bool _isAnswered = false;
bool get isAnswered => this._isAnswered;
int selectedButton;
@override
Widget build(BuildContext context) {
QuestionController _questionController =
Get.put(QuestionController());
debugPrint("Answer Print : ${note.Answer.split(",")}");
return Container(
margin: EdgeInsets.symmetric(horizontal: kDefaultPadding, vertical: 35),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(25),
),
padding: EdgeInsets.all(kDefaultPadding),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: [
...List.generate(
note.Answer.split(",").length,
(index) => OptionRadio(
index: index,
text: note.Answer.split(",")[index],
press: (val) => setState(() {
selectedButton = int.parse(val.toString());
print("$selectedButton");
}),
selectedButton: selectedButton,
// press:
// () =>{
// _isAnswered = true,
// _questionController.checkAns(note, index),
// selectedButton,
// }
),
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: TextButton(
onPressed: () async {
debugPrint("Clicked options : ${note.Answer.isNotEmpty} isAnswered: $isAnswered");
debugPrint('Check Index : ${index} check quiz model Lenght : ${QuizModel.question.length} check note Id : ${note.Id}');
if(index+1 == questionLength){
// score screen
debugPrint('Navigate to score screen');
Text(
"Submit",
style: Theme.of(context)
.textTheme
.button
.copyWith(color: Colors.white),
);
_questionController.scoreNavigation(index, context);
}
else{
if (note.Answer.isNotEmpty == !isAnswered) {
debugPrint('Clicked RadioBtn ${optionRadio.index}');
SharedPreferences prefs = await SharedPreferences.getInstance();
//Return int
int intValue = prefs.getInt('intValue');
debugPrint('Int value from sharedPrefs: $intValue');
_questionController.nextQuestion(note,intValue,"","",[]);
prefs.remove("intValue");
}else{
debugPrint('Click proper option for Radio');
}
}
},
child: Container(
width: double.infinity,
alignment: Alignment.center,
padding: EdgeInsets.all(kDefaultPadding * 0.75),
margin: EdgeInsets.all(37),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
color: Color(ColorData.button)
),
child: Text(
"Next Question",
style: Theme.of(context)
.textTheme
.button
.copyWith(color: Colors.white),
),
),
),
),
],
),
),
);
}
setState(Null Function() param0) {}
}
我从一个以逗号分隔选项的数组中获取值。 “答案”:“男,女”
【问题讨论】:
-
您需要将 'selectedButton' 值保存在 'OptionRadio' 小部件之外,并与 'Male' 的 'OptionRadio' 小部件和 'Female' 的 'OptionRadio' 小部件共享该值。
-
@KuKu 我测试了上面的方法并且能够接收到在日志中被点击的正确值,但是图标没有改变颜色。对于两者,Icon 保持未选中状态。我试图用 setState() 中的指定值制作一个小部件。选定按钮 = val;因为它是最终字段,所以无法赋值。接下来我该怎么办?
标签: flutter dart radio-button flutter-layout flutter-getx