Я новичок в трепетании и создаю приложение, которое создает проекты. Я работаю над страницей проекта просмотра, которая позволяет пользователю просматривать каждый вопрос. То, как он настроен, позволяет пользователю просмотреть вопрос, а затем нажать «Далее» (оставаясь на той же странице), чтобы просмотреть следующий вопрос. Первый initState инициализирует объект Project. Этот объект проекта затем должен go получить данные / информацию из документа. Вопросы хранятся в виде списка объектов «Вопрос», где у каждого объекта есть тип (текст, множественный выбор, цифры c, загрузка фотографий и т. Д. c), вопрос и номер. Тип вопроса используется для определения того, какой виджет отображать (например, загрузка фотографий будет отличаться от ввода текста).
Проблема, с которой я столкнулся, заключается в том, что объект проекта инициализирован, а список объектов вопроса - нет, и я получаю ошибки индексации. Однако, когда я горячо refre sh, я вижу правильный виджет (в настоящее время просто текст). Другая проблема, которая, я думаю, связана, заключается в том, что каждый раз, когда пользователь нажимает кнопку «Далее», объект переходит и снова получает все вопросы, поэтому список никогда не заканчивается. Я считаю, что проблема заключается в моих функциях getdataFromProject и questionData () в getproject.dart (первый фрагмент кода).
Я пытался использовать будущего строителя, но я не уверен, что это правильное решение. Однако моя сборка зависит от объекта, который будет завершен. Поэтому я попытался использовать переменную Future projectFuture и установить ее равной моей функции _getQuestions () (вызываемой в initState ()).
Любая помощь приветствуется.
class Questions {
final String question;
final String number;
final String type;
Questions({this.question, this.number, this.type});
List<String> answers = new List();
}
class GetProject {
//this is what keeps growing each time next is pressed
List<Questions> questions; //holds the question objects
String docID;
String title;
GetProject(String title, String docID){
this.docID = docID;
this.title=title;
questionData();
}
Future<void> get getdataFromProject async {
return await questionData();
}
Future<void> questionData() async {
int count = 0;
Future<DocumentSnapshot> snapshot =
Firestore.instance.collection('Projects').document(this.docID).get();
return await snapshot.then((DocumentSnapshot questionSnap) => {
questionSnap.data.forEach((key, value) {
if ('$key' == 'count') {
count = value;
count--;
//returncount=count;
} else if ('$key' == ('Question' + count.toString())) {
print(value['Type']);
Questions question = new Questions(
type: value['Type'],
number: value['Number'],
question: value['Question'],
);
if (value['Type'] == 'MultipleChoice') {
value['Answers'].forEach((e) {
question.answers.add(e.toString());
});
//question.answers.addAll(value['Answers']);
}
questions.add(question);
count--;
}
}),
});
}
int getType(int index) {
switch (questions[index].type) {
case 'TextInputItem':
return 0;
case 'MultipleChoice':
return 1;
case 'ShortAnswerItem':
return 2;
case 'UserLocation':
return 3;
}
return -1;
}
class ViewProject extends StatefulWidget {
final String docIDref;
final String title;
ViewProject({this.docIDref, this.title});
@override
_ViewProjectState createState() => _ViewProjectState();
}
class _ViewProjectState extends State<ViewProject> {
GetProject project;
int _currentQuestion = 0;
Future projectFuture;
int _getType(_currentQuestion) {
switch(project.questions[_currentQuestion].type){
case 'TextInputItem':
return 0;
case 'MultipleChoice':
return 1;
case 'ShortAnswerItem':
return 2;
case 'UserLocation':
return 3;
}
return -1;
}
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: AppBar(title: Text("Random Widget")),
body:
project.questions.length == 0
? Center(child: CircularProgressIndicator()
)
:
Center(child:
FutureBuilder(
initialData: 0,
future: projectFuture,
builder: (context, snapshot) {
if(project.questions.length>0){
return getQuestionWidget();
}
else{
return CircularProgressIndicator();
}
}
)
)),
);
}
Widget getQuestionWidget() {
switch(_getType(_currentQuestion++)){
case 0:
return Column(children: <Widget>[
Text("TextInputItem", textScaleFactor: 4),
getNextButton()
]);
break;
case 1:
return Column(children: <Widget>[
Text("MultipleChoice", textScaleFactor: 4),
getNextButton()
]);
break;
case 2:
return Column(children: <Widget>[
Text("ShortAnswer", textScaleFactor: 4),
getNextButton()
]);
break;
case 3:
return Column(children: <Widget>[
Text("UserLocation", textScaleFactor: 4),
getNextButton()
]);
break;
case -1:
return Column(children: <Widget>[
Text("Submit Page", textScaleFactor: 4),
//getNextButton()
]);
}
}
Widget getNextButton(){
return RaisedButton(
child: Text("NEXT"),
color: Colors.red,
onPressed: () {
if(_currentQuestion < project.questions.length){
return getQuestionWidget();
}
return Text("All done!");
//setState(() {
//_currentQuestion++;
//return getQuestionWidget();
//_getType(_currentQuestion);
// });
}
);
}
@override
void initState() {
project = new GetProject(widget.title, widget.docIDref);
//project.getdataFromProject();
//_getQuestions();
projectFuture=_getQuestions();
super.initState();
}
Future<void> _getQuestions() async {
return await project.getdataFromProject;
}
// Call this function when you want to move to the next page
void goToNextPage() {
_currentQuestion++;
}
}