Gewohnheitstracker: Serie
Teil des Abschnitts Projekte der Flutter-Journey von Coddy. Lektion 32 von 36.
Serien sorgen dafür, dass Menschen immer wiederkommen: Aufeinanderfolgende Tage fühlen sich an, als müsste man sie schützen. Hier ist die Serie die längste Reihe erledigter Tage in der Woche. Wasser trinken, von Montag bis Mittwoch und am Freitag erledigt, ergibt eine Serie von 3.
Um eine Reihe zu zählen, gehst du die Tage der Reihe nach mit zwei Zahlen durch: run, die Anzahl der bisher aufeinanderfolgenden Tage, und best, die längste bisher gesehene Reihe. Ein erledigter Tag verlängert die Reihe; ein offener Tag setzt sie auf 0 zurück.
int get streak {
int best = 0;
int run = 0;
for (bool day in days) {
if (day) {
run++;
if (run > best) best = run;
} else {
run = 0;
}
}
return best;
}Gib best zurück, nicht run: Am Ende der Schleife ist run nur der letzte Abschnitt, der 0 beträgt, wenn der Sonntag offen ist.
Zeige sie unter der Woche mit einem Flammensymbol an: orange, solange eine Serie besteht, und in dem outline-Grauton des Designs, wenn es keine gibt. „0 Tage in Folge“ klingt seltsam, sag dann also „Noch keine Serie“.
Aufgabe
SchwerSerien anzeigen:
- den Getter
streakzuHabithinzufügen - unter der Woche, nach 12 Pixeln, eine
Rowhinzufügen:Icons.local_fire_departmentin Größe 20 (orange, wenn die Serie größer als 0 ist, andernfalls dieoutlinedes Themes), 4 Pixel und den Text - der Text lautet
3 day streak(mit der tatsächlichen Zahl) oder bei 0No streak yet
Probier es selbst
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.green),
),
home: const HabitScreen(),
);
}
}
const List<String> dayNames = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
class Habit {
Habit(this.name, this.days);
final String name;
final List<bool> days;
int get done => days.where((day) => day).length;
}
class HabitScreen extends StatefulWidget {
const HabitScreen({super.key});
@override
State<HabitScreen> createState() => _HabitScreenState();
}
class _HabitScreenState extends State<HabitScreen> {
final List<Habit> _habits = [
Habit('Drink water', [true, true, true, false, true, false, false]),
Habit('Read 10 pages', [true, false, true, true, false, false, false]),
Habit('Stretch', List.filled(7, false)),
];
void _toggle(Habit habit, int day) {
setState(() {
habit.days[day] = !habit.days[day];
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Habits')),
body: ListView(
padding: const EdgeInsets.fromLTRB(16, 8, 16, 88),
children: [
for (Habit habit in _habits)
HabitCard(
habit: habit,
onToggle: (day) => _toggle(habit, day),
),
],
),
);
}
}
class HabitCard extends StatelessWidget {
const HabitCard({super.key, required this.habit, required this.onToggle});
final Habit habit;
final void Function(int day) onToggle;
@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
return Card(
margin: const EdgeInsets.only(top: 12),
clipBehavior: Clip.antiAlias,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(child: Text(habit.name, style: textTheme.titleMedium)),
Text('${habit.done} of 7 days', style: textTheme.bodySmall),
],
),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
for (int i = 0; i < 7; i++)
DayCircle(
label: dayNames[i],
done: habit.days[i],
onTap: () => onToggle(i),
),
],
),
],
),
),
);
}
}
class DayCircle extends StatelessWidget {
const DayCircle({super.key, required this.label, required this.done, required this.onTap});
final String label;
final bool done;
final VoidCallback onTap;
@override
Widget build(BuildContext context) {
final colors = Theme.of(context).colorScheme;
return GestureDetector(
onTap: onTap,
child: Container(
width: 40,
height: 40,
alignment: Alignment.center,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: done ? colors.primary : colors.surfaceContainerHighest,
),
child: Text(
label,
style: TextStyle(
fontSize: 11,
fontWeight: FontWeight.bold,
color: done ? colors.onPrimary : colors.onSurfaceVariant,
),
),
),
);
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Projekte
1Projekt: To-do-Liste
To-do-Liste: Die AufgabenlisteTo-do-Liste: Eine Aufgabe hinzufügen4Projekt: Gewohnheitstracker
Gewohnheitstracker: Deine GewohnheitenGewohnheitstracker: Die WocheÜbe selbstständig: Online-Flutter-Compiler