Dynamiske farger og adaptive lyse/mørke temaer
Tilpass fargepaletten til brukerens bakgrunnsbilde, og bytt sømløst mellom lys og mørk modus.
Dynamiske farger og adaptive lyse/mørke temaer er en gratis leksjon i Mobilutvikling med Flutter på CoddyKit. Dette er leksjon 2 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Mobilutvikling med Flutter, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Mobilutvikling med Flutter inneholder totalt 4 leksjoner.
Hvorfor dynamisk farge er viktig
Material 3 introduserte dynamic color: En app kan hente paletten fra brukerens bakgrunnsbilde (Android 12+), slik at brukergrensesnittet føles personlig og naturlig på enheten.
- På støttede enheter eksponerer systemet et
ColorSchemesom er hentet fra bakgrunnsbildet. - På eldre enheter eller andre plattformer brukes en startfarge fra merkevaren som reserve.
- Den samme logikken må produsere både et lyst og et mørkt skjema.
I denne leksjonen kobler De opp dynamisk farge, bygger adaptive lyse og mørke temaer og lar systemet avgjøre hvilket som skal vises.
Startfargen som grunnlag
Selv med dynamisk farge trenger De alltid en reserve. Material 3s ColorScheme.fromSeed genererer en komplett og tilgjengelig palett fra én enkelt startfarge.
- Send inn
brightnessfor å få den tilsvarende lyse eller mørke varianten. - Det genererte skjemaet sikrer riktig kontrast mellom roller som
primaryogonPrimary.
import 'package:flutter/material.dart';
final ColorScheme lightScheme = ColorScheme.fromSeed(
seedColor: const Color(0xFF6750A4),
brightness: Brightness.light,
);
final ColorScheme darkScheme = ColorScheme.fromSeed(
seedColor: const Color(0xFF6750A4),
brightness: Brightness.dark,
);Bygge lyse og mørke ThemeData
En ThemeData pakker inn et ColorScheme sammen med typografi og komponentstiler. Med Material 3 angir De useMaterial3: true og sender inn skjemaet.
- Opprett én
ThemeDataper lysstyrke. - Hold dem konsekvente ved å utlede begge fra den samme startfargen.
ThemeData buildTheme(ColorScheme scheme) {
return ThemeData(
useMaterial3: true,
colorScheme: scheme,
appBarTheme: AppBarTheme(
backgroundColor: scheme.surface,
foregroundColor: scheme.onSurface,
),
);
}La systemet velge modus
MaterialApp godtar både et theme (lyst) og et darkTheme. Egenskapen themeMode avgjør hvilket som er aktivt.
ThemeMode.systemfølger operativsystemets innstilling automatisk.ThemeMode.light/ThemeMode.darktvinger frem en modus (nyttig for en bryter i appen).
Med ThemeMode.system bytter Flutter sømløst når brukeren aktiverer mørkt modus i enhetsinnstillingene.
MaterialApp(
theme: buildTheme(lightScheme),
darkTheme: buildTheme(darkScheme),
themeMode: ThemeMode.system,
home: const HomePage(),
);Lese dynamisk farge fra systemet
Pakken dynamic_color eksponerer den bakgrunnsbildede paletten via widgeten DynamicColorBuilder. Builderen gir Dem valgfrie lyse og mørke ColorScheme-objekter.
- Hvis enheten støtter dynamisk farge, er begge skjemaene ikke-null.
- Hvis ikke, er de
null, og De bruker startfargen som reserve.
import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/material.dart';
DynamicColorBuilder(
builder: (ColorScheme? lightDynamic, ColorScheme? darkDynamic) {
final light = lightDynamic ?? lightScheme;
final dark = darkDynamic ?? darkScheme;
return MaterialApp(
theme: buildTheme(light),
darkTheme: buildTheme(dark),
themeMode: ThemeMode.system,
home: const HomePage(),
);
},
);Harmonisere merkevarefarger
Når De blander dynamiske bakgrunnsfarger med merkevarefargen, kan de kollidere. Hjelpefunksjonene harmonize flytter en egendefinert farge mot den dynamiske primary-fargen, slik at aksentene oppleves helhetlige.
- Bruk
harmonizeWithpå enColormed skjemaets primærfarge som mål. - Da beholder egendefinerte semantiske farger (suksess, advarsel) merkevareuttrykket samtidig som de harmonerer med bakgrunnsbildet.
import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/material.dart';
ColorScheme harmonizeScheme(ColorScheme scheme) {
return scheme.harmonized();
}
Color harmonizeBrand(Color brand, ColorScheme scheme) {
return brand.harmonizeWith(scheme.primary);
}Fargeroller, ikke hardkodede heksadesimaler
For at temaer skal tilpasse seg, må widgets lese semantiske roller fra Theme.of(context).colorScheme i stedet for hardkodede farger.
scheme.primarysammen medscheme.onPrimaryfor fremtredende handlinger.scheme.surfacesammen medscheme.onSurfacefor bakgrunner og tekst.scheme.surfaceContainerHighestfor diskrete kort.
Fordi disse rollene endres med lysstyrken, blir widgetene automatisk uavhengige av lyst og mørkt modus.
Widget buildCard(BuildContext context) {
final scheme = Theme.of(context).colorScheme;
return Container(
color: scheme.surfaceContainerHighest,
child: Text(
'Adaptive',
style: TextStyle(color: scheme.onSurface),
),
);
}Ren Dart: Velge et skjema etter lysstyrke
Beslutningslogikken for hvilket skjema som skal brukes, er vanlig Dart. Her er en liten, kjørbar modell av reserveregelen: foretrekk det dynamiske skjemaet, og bruk ellers det som er utledet fra startfargen.
- Dette gjenspeiler mønsteret
lightDynamic ?? lightScheme. - Ingen Flutter-widgets er nødvendige – bare utvelgingsregelen.
enum Brightness { light, dark }
String chooseScheme({
required Brightness brightness,
required bool supportsDynamic,
}) {
final base = supportsDynamic ? 'dynamic' : 'seed';
return '$base-${brightness.name}';
}
void main() {
print(chooseScheme(brightness: Brightness.dark, supportsDynamic: true));
print(chooseScheme(brightness: Brightness.light, supportsDynamic: false));
}En temabryter i appen
Brukere ønsker ofte å overstyre systemet. Lagre en ThemeMode i tilstanden og send den til MaterialApp. En ValueNotifier er en lettvektsmåte å bygge visningen på nytt ved endringer.
- Bruk
ThemeMode.systemsom standard, slik at bakgrunnsbilde og mørkt modus fortsatt gjelder. - La bryteren velge lyst, mørkt eller tilbake til systemet.
final themeModeNotifier = ValueNotifier<ThemeMode>(ThemeMode.system);
ValueListenableBuilder<ThemeMode>(
valueListenable: themeModeNotifier,
builder: (context, mode, _) {
return MaterialApp(
theme: buildTheme(lightScheme),
darkTheme: buildTheme(darkScheme),
themeMode: mode,
home: const HomePage(),
);
},
);Reagere på den gjeldende lysstyrken
Inne i widgets trenger De noen ganger å vite hvilken modus som faktisk vises (for eksempel for å velge en annen illustrasjon). Les dette fra det aktive temaet, ikke fra enheten, fordi en bryter i appen kan overstyre systemet.
Theme.of(context).brightnessgjenspeiler det endelige temaet.- Unngå
MediaQuery.platformBrightnessOfnår en bryter kan overstyre det.
Widget heroImage(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark;
return Image.asset(
isDark ? 'assets/hero_dark.png' : 'assets/hero_light.png',
);
}Teste begge modusene raskt
Kontroller alltid brukergrensesnittet i begge skjemaene før lansering. To praktiske vaner:
- Slå mørkt modus av og på i innstillingene på enheten eller emulatoren for å bekrefte at
ThemeMode.systemreagerer. - Tving midlertidig frem
themeMode: ThemeMode.darkfor å avdekke hardkodede farger og tekst med lav kontrast.
Vanlige feil er tekst med hardkodet Colors.black som forsvinner på en mørk flate, eller en egendefinert aksentfarge som aldri ble harmonisert med den dynamiske paletten.
Hurtigsjekk: Velge themeMode
De vil at appen automatisk skal samsvare med brukerens dynamiske farger fra bakgrunnsbildet OG følge operativsystemets innstilling for lyst eller mørkt modus, samtidig som en valgfri overstyring i appen fortsatt skal være mulig senere. Hva er den riktige grunnkonfigurasjonen?
Oppsummering: Adaptiv tematisering i Material 3
De har bygget en palett som tilpasser seg både bakgrunnsbildet og lysstyrken:
- Fallback for frø:
ColorScheme.fromSeedfor lyst og mørkt tema når dynamiske farger ikke er tilgjengelige. - Dynamiske farger:
DynamicColorBuilderleverer bakgrunnsbildebaserte skjemaer, med?? seedSchemesom fallback. - Harmonisering: bland merkevarefarger og egendefinerte farger i retning av den dynamiske primærfargen.
- Semantiske roller: les roller fra
colorSchemei stedet for hardkodede heksadesimalverdier, slik at widgeter automatisk tilpasses. - Moduskontroll:
themeMode: ThemeMode.systemsom standard, med en valgfriValueNotifier-bryter.
Tilpass dere til brukeren, bruk en god fallback, og hardkod aldri en farge som dere kunne ha lest fra skjemaet.
Lær deg Dart med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 22
- Leksjoner
- 88
Ofte stilte spørsmål
Er leksjonen «Dynamiske farger og adaptive lyse/mørke temaer» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Mobilutvikling med Flutter, inkludert «Dynamiske farger og adaptive lyse/mørke temaer», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Mobilutvikling med Flutter inneholder totalt 4 leksjoner.
Hva lærer jeg i «Dynamiske farger og adaptive lyse/mørke temaer»?
Tilpass fargepaletten til brukerens bakgrunnsbilde, og bytt sømløst mellom lys og mørk modus. Du øver på Mobilutvikling med Flutter med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Mobilutvikling med Flutter?
Ingen tidligere erfaring er nødvendig. Mobilutvikling med Flutter på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.
Hvor lang tid tar leksjonen «Dynamiske farger og adaptive lyse/mørke temaer»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Mobilutvikling med Flutter-leksjonen?
Ja. Alle Mobilutvikling med Flutter-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Material 3-fargeskjemaer og seed-farger
- Dynamiske farger og adaptive lyse/mørke temaer
- Egendefinert ThemeExtension for merkevaretokens
- Responsiv typografi og tematisering av komponenter