Dynamiczne kolory i adaptacyjne jasne oraz ciemne motywy
Dostosowuj paletę do tapety użytkownika i płynnie przełączaj się między trybem jasnym a ciemnym
Dynamiczne kolory i adaptacyjne jasne oraz ciemne motywy to bezpłatna lekcja Flutter Mobile Development na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Flutter Mobile Development, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Flutter Mobile Development zawiera 4 lekcji w sumie.
Dlaczego dynamiczny kolor ma znaczenie
Material 3 wprowadza dynamiczny kolor: paleta aplikacji może być wyprowadzana z tapety użytkownika (Android 12+), dzięki czemu interfejs sprawia wrażenie spersonalizowanego i natywnego dla urządzenia.
- Na obsługiwanych urządzeniach system udostępnia
ColorSchemeutworzony na podstawie tapety. - Na starszych urządzeniach i innych platformach używany jest zastępczy kolor bazowy marki.
- Ta sama logika musi generować zarówno jasny, jak i ciemny schemat.
W tej lekcji skonfigurują Państwo dynamiczny kolor, utworzą adaptacyjne jasne i ciemne motywy oraz pozwolą systemowi zdecydować, który z nich wyświetlić.
Kolor bazowy jako fundament
Nawet w przypadku dynamicznego koloru zawsze potrzebne jest rozwiązanie zastępcze. ColorScheme.fromSeed w Material 3 generuje kompletną, dostępną paletę na podstawie jednego koloru bazowego.
- Przekaż
brightness, aby uzyskać odpowiedni jasny lub ciemny wariant. - Wygenerowany schemat gwarantuje prawidłowy kontrast między rolami, takimi jak
primaryionPrimary.
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,
);Tworzenie jasnego i ciemnego ThemeData
Element ThemeData opakowuje ColorScheme oraz style typografii i komponentów. W Material 3 należy ustawić useMaterial3: true i przekazać schemat.
- Utwórz jeden element
ThemeDatadla każdej jasności. - Zachowaj spójność, wyprowadzając oba schematy z tego samego koloru bazowego.
ThemeData buildTheme(ColorScheme scheme) {
return ThemeData(
useMaterial3: true,
colorScheme: scheme,
appBarTheme: AppBarTheme(
backgroundColor: scheme.surface,
foregroundColor: scheme.onSurface,
),
);
}Pozwolenie systemowi na wybór trybu
MaterialApp przyjmuje zarówno theme (jasny), jak i darkTheme. Właściwość themeMode określa, który z nich jest aktywny.
ThemeMode.systemautomatycznie korzysta z ustawień systemu operacyjnego.ThemeMode.light/ThemeMode.darkwymuszają wybrany tryb (co jest przydatne w przypadku przełącznika w aplikacji).
W trybie ThemeMode.system Flutter płynnie przełącza motyw, gdy użytkownik zmieni ustawienie trybu ciemnego w urządzeniu.
MaterialApp(
theme: buildTheme(lightScheme),
darkTheme: buildTheme(darkScheme),
themeMode: ThemeMode.system,
home: const HomePage(),
);Odczytywanie dynamicznego koloru z systemu
Pakiet dynamic_color udostępnia paletę opartą na tapecie za pośrednictwem widżetu DynamicColorBuilder. Jego funkcja builder udostępnia opcjonalne jasne i ciemne elementy ColorScheme.
- Jeśli urządzenie obsługuje dynamiczny kolor, oba schematy mają wartość inną niż null.
- Jeśli nie, mają wartość
nulli używany jest kolor bazowy.
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(),
);
},
);Harmonizowanie kolorów marki
Połączenie dynamicznych kolorów tapety z kolorem marki może powodować zgrzyt wizualny. Funkcje pomocnicze harmonize przesuwają niestandardowy kolor w stronę dynamicznego koloru primary, dzięki czemu akcenty tworzą spójną całość.
- Użyj
harmonizeWithna obiekcieColor, wskazując główny kolor schematu. - Dzięki temu niestandardowe kolory semantyczne (sukcesu, ostrzeżenia) pozostają zgodne z marką i tapetą.
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);
}Role kolorów zamiast zapisanych na stałe wartości szesnastkowych
Aby motywy mogły się dostosowywać, widżety muszą odczytywać role semantyczne z Theme.of(context).colorScheme, zamiast używać kolorów zapisanych na stałe.
scheme.primarywraz zscheme.onPrimarydla wyróżnionych działań.scheme.surfacewraz zscheme.onSurfacedla teł i tekstu.scheme.surfaceContainerHighestdla subtelnych kart.
Ponieważ te role zmieniają się wraz z jasnością, widżety automatycznie stają się niezależne od jasnego i ciemnego trybu.
Widget buildCard(BuildContext context) {
final scheme = Theme.of(context).colorScheme;
return Container(
color: scheme.surfaceContainerHighest,
child: Text(
'Adaptive',
style: TextStyle(color: scheme.onSurface),
),
);
}Czysty Dart: wybór schematu według jasności
Logika decydująca o tym, którego schematu użyć, jest napisana w zwykłym języku Dart. Oto mały, uruchamialny model reguły zastępczej: najpierw wybierz schemat dynamiczny, a jeśli nie jest dostępny, użyj schematu wyprowadzonego z koloru bazowego.
- Odzwierciedla to wzorzec
lightDynamic ?? lightScheme. - Nie są potrzebne widżety Fluttera — wystarczy sama reguła wyboru.
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));
}Przełącznik motywu w aplikacji
Użytkownicy często chcą zastąpić ustawienia systemowe. Przechowuj ThemeMode w stanie i przekazuj go do MaterialApp. ValueNotifier to lekki sposób na ponowne budowanie interfejsu po zmianie.
- Ustaw domyślnie
ThemeMode.system, aby nadal obowiązywały tapeta i tryb ciemny. - Pozwól przełącznikowi wybrać tryb jasny, ciemny lub ponownie systemowy.
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(),
);
},
);Reagowanie na efektywną jasność
W widżetach czasami trzeba sprawdzić, który tryb jest faktycznie wyświetlany (na przykład aby wybrać inną ilustrację). Odczytuj tę informację z aktywnego motywu, a nie z urządzenia, ponieważ przełącznik w aplikacji może zastąpić ustawienia systemowe.
Theme.of(context).brightnessodzwierciedla rozstrzygnięty motyw.- Unikaj
MediaQuery.platformBrightnessOf, gdy przełącznik może zastąpić ustawienie systemowe.
Widget heroImage(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark;
return Image.asset(
isDark ? 'assets/hero_dark.png' : 'assets/hero_light.png',
);
}Szybkie testowanie obu trybów
Przed wydaniem aplikacji zawsze sprawdzaj interfejs w obu schematach. Dwie praktyczne metody:
- Przełącz tryb ciemny w ustawieniach urządzenia lub emulatora, aby potwierdzić, że
ThemeMode.systemreaguje prawidłowo. - Tymczasowo wymuś
themeMode: ThemeMode.dark, aby wykryć kolory zapisane na stałe i tekst o niskim kontraście.
Typowe błędy to tekst w Colors.black zapisany na stałe, który znika na ciemnej powierzchni, lub niestandardowy akcent, który nigdy nie został zharmonizowany z dynamiczną paletą.
Szybkie sprawdzenie: wybór themeMode
Chcą Państwo, aby aplikacja automatycznie dopasowywała się do dynamicznych kolorów z tapety użytkownika i jednocześnie korzystała z ustawienia jasnego lub ciemnego trybu w systemie operacyjnym, a w przyszłości nadal umożliwiała opcjonalne nadpisanie tego ustawienia w aplikacji. Jaka jest właściwa konfiguracja bazowa?
Podsumowanie: adaptacyjne motywy Material 3
Utworzył(a) Pan(i) paletę, która dopasowuje się zarówno do tapety, jak i jasności:
- Rezerwowy schemat bazowy:
ColorScheme.fromSeeddla jasnego i ciemnego motywu, gdy kolor dynamiczny jest niedostępny. - Kolor dynamiczny:
DynamicColorBuilderdostarcza schematy na podstawie tapety, a?? seedSchemezapewnia wartość rezerwową. - Harmonizacja: dopasowanie kolorów marki i niestandardowych kolorów do dynamicznego koloru podstawowego.
- Role semantyczne: odczytywanie ról
colorSchemezamiast używania zakodowanych na stałe wartości szesnastkowych, aby widżety automatycznie się przełączały. - Kontrola trybu: domyślnie
themeMode: ThemeMode.system, z opcjonalnym przełącznikiemValueNotifier.
Proszę dostosowywać interfejs do użytkownika, zapewniać rozsądne wartości rezerwowe i nigdy nie kodować na stałe koloru, który można odczytać ze schematu.
Ucz się Dart dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 22
- Lekcje
- 88
Często zadawane pytania
Czy lekcja „Dynamiczne kolory i adaptacyjne jasne oraz ciemne motywy” jest bezpłatna?
Tak — pełny tekst „Dynamiczne kolory i adaptacyjne jasne oraz ciemne motywy” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Flutter Mobile Development, przejdź na CoddyKit PRO. Kurs Flutter Mobile Development zawiera 4 lekcji w sumie.
Co nauczysz się w „Dynamiczne kolory i adaptacyjne jasne oraz ciemne motywy”?
Dostosowuj paletę do tapety użytkownika i płynnie przełączaj się między trybem jasnym a ciemnym Ćwiczysz Flutter Mobile Development z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Flutter Mobile Development?
Nie wymagamy żadnego doświadczenia. Flutter Mobile Development w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Dynamiczne kolory i adaptacyjne jasne oraz ciemne motywy”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Flutter Mobile Development?
Tak. Każda lekcja Flutter Mobile Development zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Schematy kolorów Material 3 i kolory bazowe
- Dynamiczne kolory i adaptacyjne jasne oraz ciemne motywy
- Niestandardowe ThemeExtension dla tokenów marki
- Responsywna typografia i motywy komponentów