我想创建一个调查。
在此调查中,每个问题将显示在一个页面上。根据每个问题的答案,下一步可能会向用户提出不同的问题。
例如,第一个问题,也就是在第一页上,有一个有两个选项的问题。如果用户选择第一个答案,则会在其前面出现一个新页面。如果他选择第二个答案,应该会出现一个不同的页面。
由于问题页面中会有dropdownmenu、radiobutton等项,因此在某些情况下我需要设置setstate。我在UI渲染期间在initstate中创建的项不会更新。
当在这些问题页面之间切换时,它还需要侧向滑动动画。
我应该如何使用哪种结构?有没有更符合逻辑的结构可以在PageView之外使用?
当我使用pageview时,页面中的dropdownbutton、radiobutton等项目的视图不会更新。求求你这很重要。
谢谢。
发布于 2021-01-17 15:09:15
对于动态调查表单,最好使用PageView。首先,它为您提供了方便的动画。其次,即使您删除或添加PageView的子项,它也不会抛出错误,相反,它会帮助您导航到上一页。
在这里,我为您的用例制作了一个代码片段。基于这个问题,有很大的概率取决于答案。我的回答不会涵盖所有用例,但是,您可以自定义QuestionModel以满足您的需求。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final PageController _pageController = PageController();
List<QuestionModel> _questions = [
QuestionModel(
question: 'Is elephant big?',
questionType: QuestionType.MultipleChoice,
answerList: ['yes', 'no'],
isCorrect: false,
displayDependsOnAnswerOfIndex: null,
navigateToIndexIfCorrect: 1,
questionAction: (answer) {
if (answer == 'yes') {
return true;
} else {
return false;
}
}),
QuestionModel(
question: 'If big, state the height in feet.',
questionType: QuestionType.Form,
answerList: [],
isCorrect: false,
displayDependsOnAnswerOfIndex: 0,
navigateToIndexIfCorrect: null,
questionAction: (answer) {
if (answer != null) {
return true;
} else {
return false;
}
}),
];
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
List<QuestionModel> questions = _questions.where((questionModel) {
if (questionModel.displayDependsOnAnswerOfIndex != null) {
return (_questions[questionModel.displayDependsOnAnswerOfIndex]
.isCorrect);
} else {
return true;
}
}).toList();
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Scaffold(
appBar: AppBar(
title: Text('Survey'),
),
body: PageView(
controller: _pageController,
children: questions.map((questionModel) {
if (questionModel.questionType == QuestionType.MultipleChoice) {
return Scaffold(
body: Column(
children: [
Text(questionModel.question),
Column(
children: questionModel.answerList.map((answer) {
return ListTile(
title: Text(
answer,
style: TextStyle(
fontWeight:
(answer == questionModel.choosenAnswer)
? FontWeight.bold
: FontWeight.normal,
),
),
onTap: () {
setState(() {
questionModel.choosenAnswer = answer;
questionModel.isCorrect =
questionModel.questionAction(answer);
});
if (questionModel.navigateToIndexIfCorrect !=
null &&
questionModel.isCorrect) {
_pageController.animateToPage(
questionModel.navigateToIndexIfCorrect,
duration: Duration(seconds: 1),
curve: Curves.easeInOut,
);
}
});
}).toList(),
),
],
),
);
} else if (questionModel.questionType == QuestionType.Form) {
return Scaffold(
//TODO: create implementation of form type question
body: Column(
children: [TextFormField()],
),
);
} else {
return Container();
}
}).toList(),
),
),
);
}
}
enum QuestionType {
MultipleChoice,
Form,
}
class QuestionModel {
final String question;
bool isCorrect;
String choosenAnswer;
final List<String> answerList;
final QuestionType questionType;
final int displayDependsOnAnswerOfIndex;
final int navigateToIndexIfCorrect;
final Function questionAction;
QuestionModel({
this.question,
this.choosenAnswer,
this.questionType,
this.answerList,
this.isCorrect,
this.navigateToIndexIfCorrect,
this.displayDependsOnAnswerOfIndex,
this.questionAction,
});
}https://stackoverflow.com/questions/65755055
复制相似问题