Material 3 -väriteemat ja siemenvärit
Luo harmonisia väriteemoja yhdestä siemenväristä ColorScheme.fromSeedin avulla.
Material 3 -väriteemat ja siemenvärit on ilmainen Mobiilikehitys Flutterilla-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Mobiilikehitys Flutterilla-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Mobiilikehitys Flutterilla-kurssilla on yhteensä 4 oppituntia.
Mikä on Material 3:n värijärjestelmä?
Material 3 (M3) toi käyttöön rakenteisen värijärjestelmän — joukon nimettyjä värien rooleja, joita koko sovellus käyttää yhdenmukaisesti. Sen sijaan että raakaheksadesimaaliarvoja ripoteltaisiin eri widgeteihin, määritätte rooleja, kuten primary, onPrimary, surface ja error, ja Flutterin teemoitusmoottori soveltaa niitä automaattisesti.
- primary — painikkeissa, FAB-painikkeissa ja aktiivisissa välilehdissä käytettävä brändiväri
- onPrimary — primary-värin päälle piirretty teksti tai kuvakkeet
- surface — korttien, paneelien ja valintaikkunoiden taustaväri
- onSurface — pinnoille piirretty teksti
- error / onError — kelpoisuus- ja hälytysvärit
Jokaisesta roolista on sekä vaalea että tumma muunnelma, joten voitte tukea kumpaakin teemaa yhdellä värijärjestelmän määrittelyllä.
Mihin ColorScheme.fromSeed ratkaisee ongelman
Ennen M3:a kehittäjien piti valita käsin jokainen värien rooli — primary, secondary, tertiary, pinnat, säilöt ja niiden on-vastineet. Arvoja on yli 25, ja saavutettavien kontrastisuhteiden määrittäminen käsin altistaa virheille.
ColorScheme.fromSeed ratkaisee tämän ottamalla vastaan yhden siemenvärin ja käyttämällä Googlen HCT-väriavaruuden (Hue, Chroma, Tone) algoritmia täyden, harmonisen ja WCAG:n mukaisen paletin automaattiseen luomiseen.
- Yksi syöte → yli 25 tulosroolia
- Taataan kontrasti etu- ja taustaväriparien välillä
- Vaalea ja tumma muunnelma samasta siemenväristä
- Yhdenmukainen Material You -suunnittelukielen kanssa
Ensimmäinen ColorScheme.fromSeed
ColorScheme.fromSeed-koodin käyttäminen on suoraviivaista. Välittäkää se MaterialApp-widgetin sisällä ThemeData-oliolle. Flutter hoitaa loput.
seedColor-parametri hyväksyy minkä tahansa Color-arvon — yleensä brändivärinne. Flutter johtaa siitä koko paletin.
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(
title: 'M3 Theming Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFF6750A4), // brand purple
),
useMaterial3: true,
),
home: const HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Color Scheme Demo')),
body: const Center(child: Text('Hello Material 3')),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.palette),
),
);
}
}Vaalea ja tumma teema samasta siemenväristä
Yksi ColorScheme.fromSeed-menetelmän suurimmista eduista on, että sen avulla voit luoda sekä vaalean että tumman teeman samasta siemenväristä, mikä takaa visuaalisen yhtenäisyyden eri tiloissa.
Vaihda niiden välillä välittämällä brightness-parametri. Flutter säätää sävyt automaattisesti — tummissa teemoissa siemenväristä käytetään vaaleampia sävyjä tummilla pinnoilla.
import 'package:flutter/material.dart';
const Color _brandColor = Color(0xFF00897B); // teal brand
ThemeData lightTheme() => ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: _brandColor,
brightness: Brightness.light,
),
useMaterial3: true,
);
ThemeData darkTheme() => ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: _brandColor,
brightness: Brightness.dark,
),
useMaterial3: true,
);
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: lightTheme(),
darkTheme: darkTheme(),
themeMode: ThemeMode.system, // follows device setting
home: const Scaffold(
body: Center(child: Text('Adaptive theme')),
),
);
}
}Väriroolien käyttäminen widgeteissä
Kun ColorScheme on määritetty, voit käyttää sen rooleja kaikkialla lausekkeella Theme.of(context).colorScheme. Tällöin widgetit eivät ole sidoksissa kiinteästi määritettyihin väreihin, ja ne noudattavat automaattisesti vaaleaa tai tummaa tilaa.
Widgeteissä yleisesti käytettäviä rooleja:
colorScheme.primary— interaktiivisten elementtien korostusväricolorScheme.onPrimary— ensisijaisten taustojen teksti- ja kuvakeväricolorScheme.surface— korttien ja valintaikkunoiden taustatcolorScheme.onSurface— tekstin oletusväricolorScheme.error— virhetilan ilmaisimet
import 'package:flutter/material.dart';
class StatusBadge extends StatelessWidget {
final String label;
final bool isActive;
const StatusBadge({super.key, required this.label, required this.isActive});
@override
Widget build(BuildContext context) {
final cs = Theme.of(context).colorScheme;
return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: isActive ? cs.primaryContainer : cs.surfaceContainerHighest,
borderRadius: BorderRadius.circular(20),
),
child: Text(
label,
style: TextStyle(
color: isActive ? cs.onPrimaryContainer : cs.onSurfaceVariant,
fontWeight: FontWeight.w600,
),
),
);
}
}Säilöroolit: primaryContainer ja kumppanit
M3 toi käyttöön säilöroolit — päävärien pehmeämmät ja vähemmän kromaattiset versiot, jotka on tarkoitettu käyttöliittymäelementtien, kuten sirujen, korttien ja täytettyjen painikkeiden, taustoiksi.
primaryContainer— pehmeä ensisijainen tausta (sopii esimerkiksi valituille siruille ja täytetyille tonaalisille painikkeille)onPrimaryContainer— primaryContainerin päällä käytettävä tekstisecondaryContainer/tertiaryContainer— vastaavat roolit toissijaisille ja kolmassijaisille paleteilleerrorContainer— pehmeä punainen väri tekstinsisäisille virheilmoituksille
Säilöjen käyttäminen taustoissa suoran primary-värin sijaan luo visuaalisen hierarkian ja pitää kontrastisuhteet turvallisina ilman opasiteetin manuaalista säätämistä.
import 'package:flutter/material.dart';
class InfoCard extends StatelessWidget {
final String title;
final String body;
const InfoCard({super.key, required this.title, required this.body});
@override
Widget build(BuildContext context) {
final cs = Theme.of(context).colorScheme;
return Card(
color: cs.primaryContainer,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: cs.onPrimaryContainer,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Text(
body,
style: TextStyle(color: cs.onPrimaryContainer),
),
],
),
),
);
}
}Yksittäisten roolien ohittaminen
Joskus tietylle roolille algoritmisesti luotu väri ei vastaa tarkasti brändiohjeistustasi. Voit ohittaa yksittäisiä rooleja käyttämällä lauseketta ColorScheme.fromSeed(...).copyWith(...). Tällöin kaikki automaattisesti luodut roolit säilyvät, mutta voit määrittää tietyille rooleille täsmälliset arvot.
Tämä toimintatapa on hyödyllinen esimerkiksi silloin, kun suunnittelujärjestelmäsi edellyttää error-roolille tarkkaa punaista sävyä, joka poikkeaa HCT-algoritmin tuottamasta väristä.
import 'package:flutter/material.dart';
ThemeData buildTheme() {
// Start from seed, then pin specific roles
final base = ColorScheme.fromSeed(
seedColor: const Color(0xFF1565C0), // deep blue brand
);
return ThemeData(
colorScheme: base.copyWith(
// Exact error red from our design system
error: const Color(0xFFB00020),
onError: Colors.white,
// Pin tertiary to our accent orange
tertiary: const Color(0xFFE65100),
onTertiary: Colors.white,
),
useMaterial3: true,
);
}Dynaaminen väri: taustakuvaan mukautuminen
Android 12 ja uudemmat versiot tukevat dynaamista väriä — järjestelmä poimii siemenvärin käyttäjän taustakuvasta ja käyttää sitä kaikissa sovelluksissa. Flutter tukee tätä dynamic_color-paketin avulla.
Toimintatapa on seuraava: yritä ladata järjestelmän värimalli ja käytä omaa siemenväriäsi varalla, jos värimallia ei ole saatavilla (iOS:ssä, vanhemmissa Android-versioissa tai kun käyttäjä ei ole määrittänyt taustakuvaa).
Tämä saa sovelluksen tuntumaan tuetuilla laitteilla natiivilla ja henkilökohtaisella tavalla, mutta säilyttää yhtenäisyyden muualla.
// pubspec.yaml: dynamic_color: ^1.7.0
import 'package:flutter/material.dart';
import 'package:dynamic_color/dynamic_color.dart';
const Color _fallbackSeed = Color(0xFF6750A4);
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return DynamicColorBuilder(
builder: (ColorScheme? lightDynamic, ColorScheme? darkDynamic) {
final lightScheme = lightDynamic ??
ColorScheme.fromSeed(
seedColor: _fallbackSeed,
brightness: Brightness.light,
);
final darkScheme = darkDynamic ??
ColorScheme.fromSeed(
seedColor: _fallbackSeed,
brightness: Brightness.dark,
);
return MaterialApp(
theme: ThemeData(colorScheme: lightScheme, useMaterial3: true),
darkTheme: ThemeData(colorScheme: darkScheme, useMaterial3: true),
themeMode: ThemeMode.system,
home: const Scaffold(
body: Center(child: Text('Dynamic Color')),
),
);
},
);
}
}Paletin esikatselu väriruudukolla
Kehityksen aikana on hyödyllistä näyttää kaikki keskeiset väriroolit näytöllä, jotta voit tarkistaa luodun paletin visuaalisesti. Tämä debug-näkymä on nopea tapa tarkistaa kontrasti ja yhteensopivuus ennen julkaisua.
Rakenna yksinkertainen ruudukko, joka yhdistää roolien nimet niiden väreihin ja on
-vastineisiin käyttämällä kontekstista saatavaa reaaliaikaista ColorScheme-arvoa.
import 'package:flutter/material.dart';
class PalettePreviewScreen extends StatelessWidget {
const PalettePreviewScreen({super.key});
@override
Widget build(BuildContext context) {
final cs = Theme.of(context).colorScheme;
final roles = [
('Primary', cs.primary, cs.onPrimary),
('PrimaryContainer', cs.primaryContainer, cs.onPrimaryContainer),
('Secondary', cs.secondary, cs.onSecondary),
('SecondaryContainer', cs.secondaryContainer, cs.onSecondaryContainer),
('Tertiary', cs.tertiary, cs.onTertiary),
('Surface', cs.surface, cs.onSurface),
('Error', cs.error, cs.onError),
('ErrorContainer', cs.errorContainer, cs.onErrorContainer),
];
return Scaffold(
appBar: AppBar(title: const Text('Color Palette')),
body: ListView(
children: roles.map((r) {
final (name, bg, fg) = r;
return Container(
height: 56,
color: bg,
alignment: Alignment.centerLeft,
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(name, style: TextStyle(color: fg, fontWeight: FontWeight.w500)),
);
}).toList(),
),
);
}
}Värimallien yleiset sudenkuopat
Vältä näitä virheitä käyttäessäsi M3-värimalleja:
- Heksavärien määrittäminen kiinteästi widgeteissä — Käytä aina
Theme.of(context).colorScheme.*, jotta widgetit reagoivat teeman muutoksiin ja tummaan tilaan. - Colors.white- tai Colors.black-värien käyttäminen suoraan — Ne eivät toimi oikein tummassa tilassa. Käytä niiden sijaan
colorScheme.onSurface- taicolorScheme.surface-roolia. useMaterial3: true-asetuksen unohtaminen — Ilman tätä lippua Flutter käyttää M2:n oletusarvoja, eivätkä M3:n väriroolit välttämättä vaikuta sisäänrakennettuihin widgeteihin oikein.primaryColor-arvon käyttäminen ThemeDatasta — Se on M2:n käsite. M3:ssa kaikki widgetit lukevat väritcolorScheme-arvosta. AsetaThemeData.colorScheme, äläThemeData.primaryColor.- Kirkkauden ja taustan yhteensopimattomuus — Jos luot
Brightness.dark-värimallin ja yhdistät sen valkoiseen scaffoldiin, käyttöliittymän teksti voi muuttua lukukelvottomaksi.
Kaikki yhdessä: teemallinen sovellusrakenne
Tässä on täydellinen minimaalinen sovellusrakenne, joka havainnollistaa parhaita käytäntöjä: siemeneen perustuva värimalli, vaalean ja tumman tilan tuki, useMaterial3: true sekä widgetit, jotka lukevat roolit kontekstista — missään ei käytetä kiinteästi määritettyjä värejä.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
const Color _seed = Color(0xFF2E7D32); // forest green brand
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Green Theme',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: _seed,
brightness: Brightness.light,
),
useMaterial3: true,
),
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: _seed,
brightness: Brightness.dark,
),
useMaterial3: true,
),
themeMode: ThemeMode.system,
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
final cs = Theme.of(context).colorScheme;
return Scaffold(
backgroundColor: cs.surface,
appBar: AppBar(
title: Text('Dashboard', style: TextStyle(color: cs.onPrimary)),
backgroundColor: cs.primary,
),
body: Center(
child: FilledButton.icon(
onPressed: () {},
icon: const Icon(Icons.eco),
label: const Text('Go Green'),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
backgroundColor: cs.tertiary,
foregroundColor: cs.onTertiary,
child: const Icon(Icons.add),
),
);
}
}Pikatarkistus: ColorScheme.fromSeed
Testaa ymmärrystäsi siitä, miten ColorScheme.fromSeed toimii Material 3:ssa.
Oppitunnin yhteenveto: Material 3:n värimallit ja siemenvärit
Tässä ovat oppitunnin keskeiset asiat:
- M3:n ColorScheme määrittää täydellisen joukon nimettyjä värirooleja (primary, surface, error, säilöt ja niiden
on
-vastineet), joita Flutter-widgetit käyttävät automaattisesti. - ColorScheme.fromSeed luo yli 25 roolia yhdestä brändiväristä Googlen HCT-algoritmin avulla ja takaa näin harmonian sekä saavutettavuuden.
- Välitä
brightness: Brightness.lighttaiBrightness.dark, jotta samasta siemenväristä luodaan sopiva vaalea tai tumma muunnelma — yhdistä tämä ainaMaterialApp.darkTheme-arvoon täyden tumman tilan tuen saamiseksi. - Käytä rooleja widgeteissä lausekkeella
Theme.of(context).colorScheme— älä koskaan määritä heksa-arvoja kiinteästi widgettien tiedostoissa. - Käytä säilörooleja (
primaryContainer,onPrimaryContainer) käyttöliittymäkomponenttien taustoissa; ne luovat visuaalisen hierarkian ilman opasiteetin manuaalista säätämistä. - Ohita yksittäisiä rooleja
.copyWith()-menetelmällä, kun tietyn brändivärin on oltava täsmälleen oikea. - Android 12:ssa ja uudemmissa
dynamic_color-paketin tarjoama dynaaminen väri poimii järjestelmän siemenvärin; määritä aina varaväri muita alustoja varten. - Aseta
useMaterial3: trueainaThemeData-arvolle, jotta sisäänrakennetut widgetit lukevat M3-värimallia oikein.
Opi Dart tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 22
- Oppitunnit
- 88
Usein kysytyt kysymykset
Onko oppitunti ”Material 3 -väriteemat ja siemenvärit” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Mobiilikehitys Flutterilla-oppimispolun 3 oppituntia, myös oppitunnin “Material 3 -väriteemat ja siemenvärit”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Mobiilikehitys Flutterilla-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Material 3 -väriteemat ja siemenvärit”?
Luo harmonisia väriteemoja yhdestä siemenväristä ColorScheme.fromSeedin avulla. Harjoittelet Mobiilikehitys Flutterilla-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Mobiilikehitys Flutterilla-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Mobiilikehitys Flutterilla-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.
Kuinka kauan ”Material 3 -väriteemat ja siemenvärit”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Mobiilikehitys Flutterilla-oppitunnilla?
Kyllä. Jokainen Mobiilikehitys Flutterilla-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Material 3 -väriteemat ja siemenvärit
- Dynaaminen väri ja mukautuvat vaaleat/tummat teemat
- Mukautettu ThemeExtension brändin design-tokeneille
- Responsiivinen typografia ja komponenttien teemoitus