Kuis: Main Lagi
Termasuk bagian Proyek dalam perjalanan Flutter di Coddy. Pelajaran 17 dari 36.
Kuis yang disukai orang akan dimainkan dua kali. Tambahkan tombol Main lagi di layar hasil agar kamu kembali ke pertanyaan 1 dengan skor 0.
Tombol itu sendiri hanya menutup layar hasil: Navigator.pop(context). Memulai dari awal adalah tugas layar kuis, karena indeks dan skor tersimpan dalam state-nya.
Navigator.push mengembalikan Future yang selesai saat layar yang didorong di-pop. Jadikan _next async dan gunakan await pada push: baris-baris setelahnya berjalan saat kamu kembali, dan itulah saatnya untuk mereset.
await Navigator.push(context, MaterialPageRoute(...));
setState(() {
_index = 0;
_picked = null;
_score = 0;
});Panah kembali di layar hasil juga menutup layar itu, jadi tindakan tersebut juga memulai babak baru. Layar hasil tidak punya tujuan untuk kembali, jadi itulah yang kamu inginkan.
Tantangan
SedangMainkan lagi:
- di bawah skor pada layar hasil, setelah jarak 32 piksel, tambahkan
FilledButton.icondenganIcons.replaydan labelPlay againyang menutup layar - buat
_nextmenjadiasync, gunakanawaituntuk menunggu push, lalu atur kembali indeks, jawaban, dan skor ke nilai awal di dalamsetState
Coba sendiri
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const QuizScreen(),
);
}
}
class Question {
const Question(this.text, this.answers, this.correct);
final String text;
final List<String> answers;
final int correct;
}
const List<Question> questions = [
Question('Which widget stacks its children from top to bottom?', ['Row', 'Column', 'Stack', 'Wrap'], 1),
Question('Which language do you write Flutter apps in?', ['Kotlin', 'Swift', 'Dart', 'JavaScript'], 2),
Question('What does setState do?', ['Rebuilds the widget', 'Saves the app', 'Closes the screen', 'Plays a sound'], 0),
Question('Which widget shows a list you can scroll?', ['Container', 'SizedBox', 'Padding', 'ListView'], 3),
Question('Which widget adds space around its child?', ['Padding', 'Center', 'Icon', 'Text'], 0),
];
class QuizScreen extends StatefulWidget {
const QuizScreen({super.key});
@override
State<QuizScreen> createState() => _QuizScreenState();
}
class _QuizScreenState extends State<QuizScreen> {
int _index = 0;
int? _picked;
int _score = 0;
Question get _question => questions[_index];
bool get _answered => _picked != null;
bool get _isLast => _index == questions.length - 1;
void _pick(int answer) {
if (_answered) return;
setState(() {
_picked = answer;
if (answer == _question.correct) {
_score++;
}
});
}
void _next() {
if (_isLast) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ResultsScreen(score: _score, total: questions.length),
),
);
return;
}
setState(() {
_index++;
_picked = null;
});
}
Color? _colorFor(int answer) {
if (!_answered) return null;
if (answer == _question.correct) return Colors.green;
if (answer == _picked) return Colors.red;
return null;
}
@override
Widget build(BuildContext context) {
final question = _question;
final textTheme = Theme.of(context).textTheme;
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Quiz'),
actions: [
Padding(
padding: const EdgeInsets.only(right: 16),
child: Center(
child: Text('Score: $_score', style: textTheme.titleMedium),
),
),
],
),
body: Padding(
padding: const EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'Question ${_index + 1} of ${questions.length}',
style: textTheme.labelLarge,
),
const SizedBox(height: 8),
LinearProgressIndicator(
value: (_index + 1) / questions.length,
minHeight: 8,
borderRadius: BorderRadius.circular(4),
),
const SizedBox(height: 24),
Text(question.text, style: textTheme.headlineSmall),
const SizedBox(height: 24),
for (int i = 0; i < question.answers.length; i++)
Padding(
padding: const EdgeInsets.only(bottom: 12),
child: FilledButton.tonal(
style: FilledButton.styleFrom(
backgroundColor: _colorFor(i),
foregroundColor: _colorFor(i) == null ? null : Colors.white,
padding: const EdgeInsets.all(16),
),
onPressed: () => _pick(i),
child: Text(question.answers[i]),
),
),
if (_answered) ...[
const SizedBox(height: 12),
Text(
_picked == question.correct
? 'Correct!'
: 'The answer is ${question.answers[question.correct]}',
textAlign: TextAlign.center,
style: textTheme.titleMedium,
),
const SizedBox(height: 16),
FilledButton(
onPressed: _next,
child: Text(_isLast ? 'See results' : 'Next'),
),
],
],
),
),
);
}
}
class ResultsScreen extends StatelessWidget {
const ResultsScreen({super.key, required this.score, required this.total});
final int score;
final int total;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Results')),
body: Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'You scored $score out of $total',
style: Theme.of(context).textTheme.headlineSmall,
),
],
),
),
),
);
}
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Proyek
1Proyek: Daftar Tugas
Daftar Tugas: Daftar TugasDaftar Tugas: Tambahkan Tugas4Proyek: Pelacak Kebiasaan
Pelacak Kebiasaan: KebiasaanmuPelacak Kebiasaan: Pekan IniLatihan sendiri: Compiler Flutter online