Flutter问答测试插件fastyle_quizz的使用
Flutter问答测试插件fastyle_quizz的使用
fastyle_quizz
是一个用于 fastyle
库的问答小部件集。本文将详细介绍如何在 Flutter 应用中使用 fastyle_quizz
插件,并提供一个完整的示例代码。
完整示例代码
首先,确保你已经在 pubspec.yaml
文件中添加了以下依赖项:
dependencies:
flutter:
sdk: flutter
fastyle_core: ^版本号
fastyle_quizz: ^版本号
go_router: ^版本号
tenhance: ^版本号
fastyle_buttons: ^版本号
然后,你可以使用以下代码来创建一个包含问答功能的应用:
// Flutter imports:
import 'package:flutter/material.dart';
// Package imports:
import 'package:fastyle_core/fastyle_core.dart';
import 'package:fastyle_quizz/fastyle_quizz.dart';
import 'package:go_router/go_router.dart';
import 'package:tenhance/tenhance.dart';
import 'package:fastyle_buttons/fastyle_buttons.dart';
// Project imports:
import 'package:fastyle_quizz_example/questions.dart';
void main() => runApp(const QuizApp());
class QuizApp extends StatelessWidget {
const QuizApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return FastApp(
routesForMediaType: (mediaType) => [
GoRoute(
path: '/',
builder: (_, __) => const QuizPage(),
),
],
);
}
}
class QuizPage extends StatefulWidget {
const QuizPage({super.key});
[@override](/user/override)
QuizPageState createState() => QuizPageState();
}
class QuizPageState extends State<QuizPage> {
int currentQuestionIndex = 0; // 当前问题的索引
double currentScore = 0; // 当前得分
int currentAnswerIndex = -1; // 当前答案的索引
int totalQuestions = 10; // 总问题数量
List<bool> answeredCorrectly = List.generate(10, (index) => false); // 跟踪答案
bool answered = false; // 跟踪当前问题是否已回答
bool isCorrect = false; // 跟踪所选答案是否正确
double get currentProgress {
return (currentQuestionIndex + 1) / totalQuestions * 100;
}
List<FastQuestion> questions = kQuestions;
void handleAnswer(int answerIndex) {
setState(() {
final question = questions[currentQuestionIndex];
isCorrect = answerIndex == question.correctIndex;
currentAnswerIndex = answerIndex;
answered = true;
if (isCorrect) answeredCorrectly[currentQuestionIndex] = true;
Future.delayed(const Duration(milliseconds: 600), () {
if (currentQuestionIndex < totalQuestions - 1) {
setState(() {
currentQuestionIndex++;
answered = false;
});
} else {
// 导航到结果屏幕
}
});
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return FastSectionPage(
showAppBar: false,
child: SafeArea(
top: false,
bottom: true,
child: buildLayout(),
),
);
}
Widget buildLayout() {
return FastMediaLayoutBuilder(
builder: (context, mediaType) {
final SizedBox spacer = buildSpacer(mediaType);
return Column(
children: [
buildProgress(context, mediaType),
spacer,
Expanded(
child: Builder(
builder: (context) {
if (mediaType >= FastMediaType.tablet) {
return buildLandscapeLayout(context, mediaType);
}
return buildPortraitLayout(context, mediaType);
},
),
),
kFastSizedBox16,
],
);
},
);
}
Widget buildProgress(BuildContext context, FastMediaType mediaType) {
final palette = ThemeHelper.getPaletteColors(context).gray;
double size = 48.0;
if (mediaType >= FastMediaType.desktop) {
size = 96.0;
} else if (mediaType >= FastMediaType.tablet) {
size = 64.0;
}
return FastCircleProgress(
strokeWidth: mediaType >= FastMediaType.desktop ? 6.0 : 4.0,
progressColor: ThemeHelper.colors.getPrimaryColor(context),
backgroundColor: palette.lightest,
labelText: (currentQuestionIndex + 1).toString(),
currentProgress: currentProgress,
height: size,
width: size,
);
}
SizedBox buildSpacer(FastMediaType mediaType) {
SizedBox spacing = kFastSizedBox24;
if (mediaType >= FastMediaType.desktop) {
spacing = kFastSizedBox48;
} else if (mediaType >= FastMediaType.tablet) {
spacing = kFastSizedBox32;
}
return spacing;
}
Widget buildPortraitLayout(BuildContext context, FastMediaType mediaType) {
final question = questions[currentQuestionIndex];
final SizedBox spacer = buildSpacer(mediaType);
return LayoutBuilder(builder: (context, constraints) {
final maxHeight = constraints.maxHeight;
double heightFactor = 1;
if (maxHeight > 800) {
heightFactor = 0.8;
}
return FractionallySizedBox(
heightFactor: heightFactor,
child: Column(
children: [
Expanded(child: buildMedia(context)),
spacer,
buildQuestion(context, mediaType),
spacer,
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: buildAnswerOptions(
context,
mediaType,
question.options,
),
),
],
),
);
});
}
Widget buildLandscapeLayout(BuildContext context, FastMediaType mediaType) {
final question = questions[currentQuestionIndex];
return LayoutBuilder(builder: (context, constraints) {
final maxHeight = constraints.maxHeight;
double heightFactor = 1;
double widthFactor = 1;
if (maxHeight > 800) {
heightFactor = 0.5;
} else if (maxHeight > 600) {
heightFactor = 0.65;
} else if (maxHeight > 480) {
heightFactor = 0.75;
}
if (mediaType >= FastMediaType.large) {
widthFactor = 0.75;
} else if (mediaType >= FastMediaType.desktop) {
widthFactor = 0.8;
}
return FractionallySizedBox(
widthFactor: widthFactor,
heightFactor: heightFactor,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(child: buildMedia(context)),
kFastHorizontalSizedBox48,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(child: buildQuestion(context, mediaType)),
...buildAnswerOptions(context, mediaType, question.options),
],
),
)
],
),
);
});
}
Widget buildQuestion(BuildContext context, FastMediaType mediaType) {
final question = questions[currentQuestionIndex];
double fontSize = kFastFontSize24;
if (mediaType >= FastMediaType.desktop) {
fontSize = kFastFontSize40;
} else if (mediaType >= FastMediaType.tablet) {
fontSize = kFastFontSize34;
}
return ConstrainedBox(
constraints: const BoxConstraints(minHeight: 60),
child: Align(
alignment: mediaType >= FastMediaType.tablet
? Alignment.topCenter
: Alignment.center,
child: FastTitle(
textAlign: TextAlign.center,
text: question.text,
fontSize: fontSize,
),
),
);
}
Widget buildMedia(BuildContext context) {
final palette = ThemeHelper.getPaletteColors(context).blueGray;
return ColoredBox(
color: palette.ultraLight,
child: const Center(
child: FastSecondaryBody(text: 'Media Illustration'),
),
);
}
List<Widget> buildAnswerOptions(
BuildContext context,
FastMediaType mediaType,
List<String> options,
) {
EdgeInsets padding = kFastEdgeInsets4;
if (mediaType >= FastMediaType.desktop) {
padding = kFastEdgeInsets8;
} else if (mediaType >= FastMediaType.tablet) {
padding = kFastEdgeInsets6;
}
return options.asMap().entries.map((entry) {
return Padding(
padding: padding,
child: buildAnswerOption(
context,
entry.key,
entry.value,
),
);
}).toList();
}
Widget buildAnswerOption(BuildContext context, int answerIndex, String text) {
return FastRaisedButton2(
onTap: !answered ? () => handleAnswer(answerIndex) : null,
color: _determineButtonColor(context, answerIndex),
labelText: text,
);
}
Color _determineButtonColor(BuildContext context, int answerIndex) {
if (!answered) {
return ThemeHelper.colors.getPrimaryColor(context);
}
final palettes = ThemeHelper.getPaletteColors(context);
if (currentAnswerIndex == answerIndex) {
return isCorrect ? palettes.green.dark : palettes.red.dark;
}
return palettes.gray.light;
}
}
更多关于Flutter问答测试插件fastyle_quizz的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter问答测试插件fastyle_quizz的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
fastyle_quizz
是一个用于在 Flutter 应用中创建和管理问答测试(Quiz)的插件。它提供了一些便捷的组件和功能,帮助你快速构建互动式的问答界面。以下是如何使用 fastyle_quizz
插件的基本步骤和示例。
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 fastyle_quizz
依赖:
dependencies:
flutter:
sdk: flutter
fastyle_quizz: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来安装依赖。
2. 导入包
在你的 Dart 文件中导入 fastyle_quizz
包:
import 'package:fastyle_quizz/fastyle_quizz.dart';
3. 创建问答数据
你需要准备一些问答数据,通常是一个包含问题和选项的列表。例如:
List<FastQuestion> questions = [
FastQuestion(
question: 'What is the capital of France?',
options: ['Paris', 'London', 'Berlin', 'Madrid'],
correctAnswerIndex: 0,
),
FastQuestion(
question: 'Which planet is known as the Red Planet?',
options: ['Earth', 'Mars', 'Jupiter', 'Saturn'],
correctAnswerIndex: 1,
),
FastQuestion(
question: 'Who wrote "Romeo and Juliet"?',
options: ['William Shakespeare', 'Charles Dickens', 'Mark Twain', 'Jane Austen'],
correctAnswerIndex: 0,
),
];
4. 使用 FastQuizz
组件
在你的 Widget
中使用 FastQuizz
组件来显示问答界面:
class QuizScreen extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Quiz'),
),
body: FastQuizz(
questions: questions,
onCompleted: (score) {
// 当问答完成时调用
print('Quiz completed! Your score: $score');
// 这里可以导航到结果页面或显示一个对话框
},
),
);
}
}
5. 处理完成事件
FastQuizz
组件提供了一个 onCompleted
回调函数,当用户完成所有问题时会触发该回调。你可以在回调中处理用户的得分,并导航到结果页面或显示一个对话框。
6. 自定义外观和行为
FastQuizz
组件允许你通过传递不同的参数来自定义外观和行为。例如,你可以自定义按钮颜色、文本样式、动画效果等。
FastQuizz(
questions: questions,
onCompleted: (score) {
print('Quiz completed! Your score: $score');
},
buttonColor: Colors.blue,
textStyle: TextStyle(fontSize: 16, color: Colors.black),
showCorrectAnswer: true,
);
7. 导航到结果页面
你可以在 onCompleted
回调中导航到一个结果页面,显示用户的得分和其他信息。
onCompleted: (score) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ResultScreen(score: score),
),
);
}
8. 结果页面示例
创建一个简单的结果页面来显示用户的得分:
class ResultScreen extends StatelessWidget {
final int score;
ResultScreen({required this.score});
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Quiz Result'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Your Score: $score',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Retry'),
),
],
),
),
);
}
}