4

I want to create a survey.

In this survey, each question will be displayed on one page. According to the answer of each question, different questions may be asked to the user in the next step.

For example; the first question, that is, on the first page, there is a question with two options. If the user chooses the 1st answer, a new page will appear in front of it. If he chooses the second answer, a different page should appear.

Since there will be items such as dropdownmenu, radiobutton in the question pages, there are situations where I need to setstate. The items that I created in initstate during UI rendering are not updated.

It also needs to slide animated sideways when switching between these question pages.

How should I use which structure? Is there a more logical structure I can use outside of PageView?

When I use pageview, the views of items such as dropdownbutton, radiobutton in the pages are not updated. Please this is important.

Thank you.

1
  • are you creating PageView items in build method, or are you saving them in your widget?
    – mfkw1
    Commented Jan 16, 2021 at 23:32

1 Answer 1

1

It is best if you use PageView for a dynamic survey form. First, it provides you with animation which comes in handy. Secondly, even if you remove or add children of the PageView, it will not be throwing you an error, instead, it will help you navigate to the previous page.

Here I make a snippet for your use case. Based on the question, there is a lot of probability depending on the answer. My answer will not cover all the use cases, however, you can customize QuestionModel to suit your needs.

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,
  });
}


0

Not the answer you're looking for? Browse other questions tagged or ask your own question.