Q&A Widget
.png%3Fraw%3Dtrue)
A Flutter package for displaying questions with multiple-choice radio button options, designed with the MVVM (Model-View-ViewModel) architecture in mind. This package provides a reusable QuestionWidget and a QuestionViewModel to manage your question data and user selections, making your UI logic clean and testable.
Features
-
MVVM Architecture: Separates UI, UI logic, and data for better maintainability and testability.
-
Dynamic Question Display: Easily display a list of questions with their respective radio button choices.
-
JSON Output: Provides a JSON output to the debug console for each selected answer, including the question ID and text, suitable for database storage.
-
Customizable Questions: Use your own list of
QuestionChoicesobjects to populate the widgets.
Installation
Add this to your pubspec.yaml file:
dependencies:
q_and_a_widget: ^0.0.1 # Replace with the latest version
Then, run flutter pub get in your project's root directory.
How to Use
1. Define Your Questions
Your questions should be represented by the QuestionChoices model provided by the package.
import 'package:q_and_a_widget/q_and_a_widget.dart';
final List<QuestionChoices> myQuestions = const [
QuestionChoices(
id: 'q1', // Unique ID for the question
question: 'What is the capital of France?',
choices: ['Berlin', 'Madrid', 'Paris', 'Rome'],
),
QuestionChoices(
id: 'q2', // Unique ID for the question
question: 'Which planet is closest to the Sun?',
choices: ['Earth', 'Mars', 'Mercury', 'Venus'],
),
// Add more questions as needed
];
2. Initialize the ViewModel
In your StatefulWidget's initState method, create an instance of QuestionViewModel, optionally passing your custom list of questions.
import 'package:flutter/material.dart';
import 'package:q_and_a_widget/q_and_a_widget.dart';
class MyQuizPage extends StatefulWidget {
const MyQuizPage({Key? key}) : super(key: key);
@override
State<MyQuizPage> createState() => _MyQuizPageState();
}
class _MyQuizPageState extends State<MyQuizPage> {
final List<QuestionChoices> _myCustomQuestions = const [
QuestionChoices(id: 'c1', question: 'What is the largest animal on Earth?', choices: ['Elephant', 'Blue Whale', 'Giraffe', 'Great White Shark']),
QuestionChoices(id: 'c2', question: 'Which gas do plants absorb from the atmosphere?', choices:['Oxygen', 'Nitrogen', 'Carbon Dioxide', 'Hydrogen']),
];
late final QuestionViewModel _viewModel;
@override
void initState() {
super.initState();
_viewModel = QuestionViewModel(questions: _myCustomQuestions); // Pass your custom questions
// If you want to use the default dummy questions, simply do:
// _viewModel = QuestionViewModel();
}
@override
Widget build(BuildContext context) {
// ... your UI code ...
return Scaffold(
appBar: AppBar(title: const Text('My Quiz')),
body: SingleChildScrollView(
child: Column(
children: [
// Loop through questions from the ViewModel
..._viewModel.questions.map<Widget>((questionData) {
return QuestionWidget(
questionData: questionData,
onChoiceSelected: _viewModel.handleChoiceSelected,
);
}).toList(),
],
),
),
);
}
}
3. Display the Widgets
Use the QuestionWidget within your Flutter UI, passing the QuestionChoices object and the handleChoiceSelected callback from your ViewModel.
// Inside your build method, after initializing _viewModel:
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
..._viewModel.questions.map<Widget>((questionData) {
return Column(
children: [
QuestionWidget(
questionData: questionData,
onChoiceSelected: _viewModel.handleChoiceSelected,
),
const SizedBox(height: 30), // Space between widgets
],
);
}).toList(),
],
)
Preview
Here's how the Q&A Widget looks in action:

JSON Output Format
When a user selects an answer, the handleChoiceSelected method in QuestionViewModel will print a JSON object representing all currently selected answers as a list to the debug console (e.g., in VS Code's Debug Console or your terminal where flutter run is executing).
Example JSON output for multiple selections:
[
{
"question_id": "c1",
"question_text": "What is the largest animal on Earth?",
"selected_answer": "Blue Whale"
},
{
"question_id": "c2",
"question_text": "Which gas do plants absorb from the atmosphere?",
"selected_answer": "Carbon Dioxide"
}
]
This output is designed to be easily parsed and stored in a database.
Contributing
Contributions are welcome! Please feel free to open an issue or submit a pull request on the GitHub repository.
License
This package is distributed under the MIT License.