在弹出的屏幕上有一个问题选项板,用户点击要显示该问题的问题编号,然后单击下一步按钮以显示下一个问题。
如果我使用问题选项板在问题之间遍历,则可以正常工作,但是当我单击“下一步”按钮时,它不会将选项板上的问题号变为绿色(我希望该问题号变为绿色),并且不返回下一个问题,而是循环进行迭代。当我按下按钮一段时间后,它表示没有其他问题,因为在循环结束时我已设置了此消息。
这是我的代码:
class quizpage extends StatefulWidget{
var questions,surveyid;
quizpage(this.questions,this.surveyid);
//quizpage({Key key, @required this.questions}) : super(key : key);
@override
_quizpageState createState() => _quizpageState(questions,surveyid);
}
class _quizpageState extends State<quizpage> with SingleTickerProviderStateMixin {
var questions,surveyid;
_quizpageState(this.questions,this.surveyid);
int i = 0;
int flag = 0;
int counter = 0;
int length;
Map<String, Color> btncolor = {
"1" : Colors.grey,
"2" : Colors.grey,
"3" : Colors.grey,
"4" : Colors.grey,
"5" : Colors.grey,
"6" : Colors.grey,
"7" : Colors.grey,
"8" : Colors.grey,
"9" : Colors.grey,
};
final answercontroller = TextEditingController();
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitDown, DeviceOrientation.portraitUp
]);
SizeConfig().init(context);
// TODO: implement build
return Scaffold(
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SizedBox(
height: 600,
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Numberofquestion()
],
),
),
Expanded(
flex: 4,
child: Center(
child: Container(
width: 400,
height: 400,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
width: 250,
child: Material(
elevation: 5,
color: Colors.deepOrange,
borderRadius: BorderRadius.all(
Radius.circular(10.0)),
child: TextField(
enabled: false,
maxLines: 6,
decoration: InputDecoration(
fillColor: Colors.white,
filled: true,
hintText: questions[i]
),
style: TextStyle(
fontSize: 20,
color: Colors.black
),
),
),
)
],
),
),
)
),
Expanded(
flex: 2,
child: Center(
child: Container(
width: 300,
height: 300,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
width: 250,
child: Material(
elevation: 2,
color: Colors.deepOrange,
borderRadius: BorderRadius.all(
Radius.circular(10.0)),
child: TextField(
controller: answercontroller,
maxLines: 1,
//enabled: false,
decoration: InputDecoration(
fillColor: Colors.white,
filled: true,
hintText: 'Answer'
),
style: TextStyle(
fontSize: 20,
color: Colors.black
),
),
),
),
]
)
)
)
),
Expanded(
flex: 2,
child: Align(
alignment: Alignment.topCenter,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(onPressed: SkipQuestion,
color: Colors.deepOrange,
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0))),
child: Text('Skip',
style: TextStyle(
fontSize: 20
),
),
),
RaisedButton(onPressed: NextQuestion,
color: Colors.green,
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0))),
child: Text('Next',
style: TextStyle(
fontSize: 20
),
),
),
],
),
],
),
)
)
],
),
),
),
),
);
}
@override
void setState(fn) {
// TODO: implement setState
super.setState(fn);
if(btncolor[(i+1).toString()] == Colors.deepOrange){
btncolor[(i+1).toString()] = Colors.purple;
flag = 1;
}
else if(btncolor[(i+1).toString()] == Colors.green){
btncolor[(i+1).toString()] = Colors.purple;
flag = 2;
}
else{
btncolor[(i+1).toString()] = Colors.purple;
}
}
void NextQuestion() async {
if(answercontroller.text.length == 0){
await showDialog(
context: context,
builder: (context) => new AlertDialog(
title: new Text('Alert'),
content: Text(
'Please enter an answer.'),
actions: <Widget>[
new FlatButton(
onPressed: () {
Navigator.of(context, rootNavigator: true)
.pop(); // dismisses only the dialog and returns nothing
},
child: new Text('OK'),
),
],
),
);
}
else{
setState(() async {
if(i < (questions.length - 1)){
// ignore: unnecessary_statements
btncolor[(i+1).toString()] = Colors.green;
i++;
}
else{
await showDialog(
context: context,
builder: (context) => new AlertDialog(
title: new Text('Alert'),
content: Text(
'There are no next questions.'),
actions: <Widget>[
new FlatButton(
onPressed: () {
Navigator.of(context, rootNavigator: true)
.pop(); // dismisses only the dialog and returns nothing
},
child: new Text('OK'),
),
],
),
);
}
});
}
}
@override
void initState() {
SystemChrome.setEnabledSystemUIOverlays([]);
super.initState();
}
void SkipQuestion() {
setState(() {
if(i < (questions.length - 1)){
// ignore: unnecessary_statements
btncolor[(i+1).toString()] = Colors.deepOrange;
i++;
}
else{
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => resultpage(surveyid),
));
}
});
}
void ChooseQuestion() {
setState(() {
if(i < (questions.length)){
for(int k =0; k< (questions.length); k++){
if(k != i){
if(btncolor[(k+1).toString()] == Colors.purple){
if(flag == 1){
btncolor[(k+1).toString()] = Colors.red;
flag =0;
}
else if(flag == 2){
btncolor[(k+1).toString()] = Colors.green;
flag =0;
}
else{
btncolor[(k+1).toString()] = Colors.grey;
}
}
}
else{
if(btncolor[(k+1).toString()] == Colors.purple){
if(flag == 1){
btncolor[(k+1).toString()] = Colors.red;
}
else if(flag == 2){
btncolor[(k+1).toString()] = Colors.green;
flag =0;
}
else{
btncolor[(k+1).toString()] = Colors.grey;
}
}
}
}
//i++;
}
else{
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => resultpage(surveyid),
));
}
});
}
Widget Numberofquestion() {
if(questions.length == 9){
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
width: 40,
padding: EdgeInsets.all(5),
child: RaisedButton(onPressed: () {
i = 0;
ChooseQuestion();
},
color: btncolor["1"],
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0))),
child: Text("1",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20
),
),
),
),
Container(
width: 40,
padding: EdgeInsets.all(5),
child: RaisedButton(onPressed: () {
i = 1;
ChooseQuestion();
},
color: btncolor["2"],
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0))),
child: Text('2',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20
),
),
),
),
Container(
width: 40,
padding: EdgeInsets.all(5),
child: RaisedButton(onPressed: () {
i = 2;
ChooseQuestion();
},
color: btncolor["3"],
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0))),
child: Text('3',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20
),
),
),
),
Container(
width: 40,
padding: EdgeInsets.all(5),
child: RaisedButton(onPressed: () {
i = 3;
ChooseQuestion();
},
color: btncolor["4"],
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(10.0))),
child: Text('4',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 20
),
),
),
),
],
);
}
}
}
在这里,问题是存储问题的数组。
当我使用“跳过”按钮时,setState可以正常工作,但是当我使用“下一步”按钮时,setState无法工作。
有人可以帮我吗?
答案 0 :(得分:1)
我想你是在错误地操纵国家
docs所指:
@protected
void setState (VoidCallback fn)
所提供的回调立即被同步调用。它一定不能返回future(回调不能是异步的),因为从那时起,不清楚何时实际设置状态。
注意事项:
您可能会看到link,希望它有用
答案 1 :(得分:0)
尝试
@override
void setState(fn) {
if(btncolor[(i+1).toString()] == Colors.deepOrange){
btncolor[(i+1).toString()] = Colors.purple;
flag = 1;
}
else if(btncolor[(i+1).toString()] == Colors.green){
btncolor[(i+1).toString()] = Colors.purple;
flag = 2;
}
else{
btncolor[(i+1).toString()] = Colors.purple;
}
super.setState(fn);//move here
}