Add contrastLevel
parameter to ColorScheme.fromSeed
(#149705)
This PR is to add a parameter `contrastLevel` to `ColorScheme.fromSeed` so that we can construct high contrast `ColorScheme`. https://github.com/flutter/flutter/assets/36861262/c609c996-5dfe-4c6c-800c-349a99de4256 Related to https://github.com/flutter/flutter/issues/149683
This commit is contained in:
parent
d46463056c
commit
3ed3f31ba6
@ -20,8 +20,17 @@ class ColorSchemeExample extends StatefulWidget {
|
|||||||
class _ColorSchemeExampleState extends State<ColorSchemeExample> {
|
class _ColorSchemeExampleState extends State<ColorSchemeExample> {
|
||||||
Color selectedColor = ColorSeed.baseColor.color;
|
Color selectedColor = ColorSeed.baseColor.color;
|
||||||
Brightness selectedBrightness = Brightness.light;
|
Brightness selectedBrightness = Brightness.light;
|
||||||
|
double selectedContrast = 0.0;
|
||||||
static const List<DynamicSchemeVariant> schemeVariants = DynamicSchemeVariant.values;
|
static const List<DynamicSchemeVariant> schemeVariants = DynamicSchemeVariant.values;
|
||||||
|
|
||||||
|
void updateTheme(Brightness brightness, Color color, double contrastLevel) {
|
||||||
|
setState(() {
|
||||||
|
selectedBrightness = brightness;
|
||||||
|
selectedColor = color;
|
||||||
|
selectedContrast = contrastLevel;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
@ -30,45 +39,27 @@ class _ColorSchemeExampleState extends State<ColorSchemeExample> {
|
|||||||
colorScheme: ColorScheme.fromSeed(
|
colorScheme: ColorScheme.fromSeed(
|
||||||
seedColor: selectedColor,
|
seedColor: selectedColor,
|
||||||
brightness: selectedBrightness,
|
brightness: selectedBrightness,
|
||||||
|
contrastLevel: selectedContrast,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
home: Builder(
|
home: Scaffold(
|
||||||
builder: (BuildContext context) => Scaffold(
|
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('ColorScheme'),
|
title: const Text('ColorScheme'),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
Row(
|
IconButton(
|
||||||
children: <Widget>[
|
icon: const Icon(Icons.settings),
|
||||||
const Text('Color Seed'),
|
|
||||||
MenuAnchor(
|
|
||||||
builder: (BuildContext context, MenuController controller, Widget? widget) {
|
|
||||||
return IconButton(
|
|
||||||
icon: Icon(Icons.circle, color: selectedColor),
|
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
showModalBottomSheet<void>(
|
||||||
if (!controller.isOpen) {
|
barrierColor: Colors.transparent,
|
||||||
controller.open();
|
context: context,
|
||||||
}
|
builder: (BuildContext context) => Settings(
|
||||||
});
|
selectedColor: selectedColor,
|
||||||
},
|
selectedBrightness: selectedBrightness,
|
||||||
|
selectedContrast: selectedContrast,
|
||||||
|
updateTheme: updateTheme
|
||||||
|
)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
menuChildren: List<Widget>.generate(ColorSeed.values.length, (int index) {
|
|
||||||
final Color itemColor = ColorSeed.values[index].color;
|
|
||||||
return MenuItemButton(
|
|
||||||
leadingIcon: selectedColor == ColorSeed.values[index].color
|
|
||||||
? Icon(Icons.circle, color: itemColor)
|
|
||||||
: Icon(Icons.circle_outlined, color: itemColor),
|
|
||||||
onPressed: () {
|
|
||||||
setState(() {
|
|
||||||
selectedColor = itemColor;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
child: Text(ColorSeed.values[index].label),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -78,23 +69,6 @@ class _ColorSchemeExampleState extends State<ColorSchemeExample> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 24.0),
|
|
||||||
child: Row(
|
|
||||||
children: <Widget>[
|
|
||||||
const Text('Brightness'),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Switch(
|
|
||||||
value: selectedBrightness == Brightness.light,
|
|
||||||
onChanged: (bool value) {
|
|
||||||
setState(() {
|
|
||||||
selectedBrightness = value ? Brightness.light : Brightness.dark;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SingleChildScrollView(
|
SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -103,6 +77,7 @@ class _ColorSchemeExampleState extends State<ColorSchemeExample> {
|
|||||||
selectedColor: selectedColor,
|
selectedColor: selectedColor,
|
||||||
brightness: selectedBrightness,
|
brightness: selectedBrightness,
|
||||||
schemeVariant: schemeVariants[index],
|
schemeVariant: schemeVariants[index],
|
||||||
|
contrastLevel: selectedContrast,
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
),
|
),
|
||||||
@ -112,6 +87,105 @@ class _ColorSchemeExampleState extends State<ColorSchemeExample> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Settings extends StatefulWidget {
|
||||||
|
const Settings({
|
||||||
|
super.key,
|
||||||
|
required this.updateTheme,
|
||||||
|
required this.selectedBrightness,
|
||||||
|
required this.selectedContrast,
|
||||||
|
required this.selectedColor,
|
||||||
|
});
|
||||||
|
|
||||||
|
final Brightness selectedBrightness;
|
||||||
|
final double selectedContrast;
|
||||||
|
final Color selectedColor;
|
||||||
|
|
||||||
|
final void Function(Brightness, Color, double) updateTheme;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<Settings> createState() => _SettingsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SettingsState extends State<Settings> {
|
||||||
|
late Brightness selectedBrightness = widget.selectedBrightness;
|
||||||
|
late Color selectedColor = widget.selectedColor;
|
||||||
|
late double selectedContrast = widget.selectedContrast;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Theme(
|
||||||
|
data: Theme.of(context).copyWith(colorScheme: ColorScheme.fromSeed(
|
||||||
|
seedColor: selectedColor,
|
||||||
|
contrastLevel: selectedContrast,
|
||||||
|
brightness: selectedBrightness,
|
||||||
|
)),
|
||||||
|
child: ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(maxHeight: 200),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(20.0),
|
||||||
|
child: ListView(
|
||||||
|
children: <Widget>[
|
||||||
|
Center(child: Text('Settings', style: Theme.of(context).textTheme.titleLarge)),
|
||||||
|
Row(
|
||||||
|
children: <Widget>[
|
||||||
|
const Text('Brightness: '),
|
||||||
|
Switch(
|
||||||
|
value: selectedBrightness == Brightness.light,
|
||||||
|
onChanged: (bool value) {
|
||||||
|
setState(() {
|
||||||
|
selectedBrightness = value ? Brightness.light : Brightness.dark;
|
||||||
|
});
|
||||||
|
widget.updateTheme.call(selectedBrightness, selectedColor, selectedContrast);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Wrap(
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
const Text('Seed color: '),
|
||||||
|
...List<Widget>.generate(ColorSeed.values.length, (int index) {
|
||||||
|
final Color itemColor = ColorSeed.values[index].color;
|
||||||
|
return IconButton(
|
||||||
|
icon: selectedColor == ColorSeed.values[index].color
|
||||||
|
? Icon(Icons.circle, color: itemColor)
|
||||||
|
: Icon(Icons.circle_outlined, color: itemColor),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
selectedColor = itemColor;
|
||||||
|
});
|
||||||
|
widget.updateTheme.call(selectedBrightness, selectedColor, selectedContrast);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: <Widget>[
|
||||||
|
const Text('Contrast level: '),
|
||||||
|
Expanded(
|
||||||
|
child: Slider(
|
||||||
|
divisions: 4,
|
||||||
|
label: selectedContrast.toString(),
|
||||||
|
min: -1,
|
||||||
|
value: selectedContrast,
|
||||||
|
onChanged: (double value) {
|
||||||
|
setState(() {
|
||||||
|
selectedContrast = value;
|
||||||
|
});
|
||||||
|
widget.updateTheme.call(selectedBrightness, selectedColor, selectedContrast);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -122,11 +196,13 @@ class ColorSchemeVariantColumn extends StatelessWidget {
|
|||||||
super.key,
|
super.key,
|
||||||
this.schemeVariant = DynamicSchemeVariant.tonalSpot,
|
this.schemeVariant = DynamicSchemeVariant.tonalSpot,
|
||||||
this.brightness = Brightness.light,
|
this.brightness = Brightness.light,
|
||||||
|
this.contrastLevel = 0.0,
|
||||||
required this.selectedColor,
|
required this.selectedColor,
|
||||||
});
|
});
|
||||||
|
|
||||||
final DynamicSchemeVariant schemeVariant;
|
final DynamicSchemeVariant schemeVariant;
|
||||||
final Brightness brightness;
|
final Brightness brightness;
|
||||||
|
final double contrastLevel;
|
||||||
final Color selectedColor;
|
final Color selectedColor;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -148,6 +224,7 @@ class ColorSchemeVariantColumn extends StatelessWidget {
|
|||||||
colorScheme: ColorScheme.fromSeed(
|
colorScheme: ColorScheme.fromSeed(
|
||||||
seedColor: selectedColor,
|
seedColor: selectedColor,
|
||||||
brightness: brightness,
|
brightness: brightness,
|
||||||
|
contrastLevel: contrastLevel,
|
||||||
dynamicSchemeVariant: schemeVariant,
|
dynamicSchemeVariant: schemeVariant,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -9,7 +9,8 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
void main() {
|
void main() {
|
||||||
testWidgets('ColorScheme Smoke Test', (WidgetTester tester) async {
|
testWidgets('ColorScheme Smoke Test', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
const example.ColorSchemeExample(),
|
const MaterialApp(home: example.ColorSchemeExample()
|
||||||
|
),
|
||||||
);
|
);
|
||||||
expect(find.text('tonalSpot (Default)'), findsOneWidget);
|
expect(find.text('tonalSpot (Default)'), findsOneWidget);
|
||||||
|
|
||||||
@ -18,7 +19,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('Change color seed', (WidgetTester tester) async {
|
testWidgets('Change color seed', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
const example.ColorSchemeExample(),
|
const MaterialApp(home: example.ColorSchemeExample()),
|
||||||
);
|
);
|
||||||
|
|
||||||
ColoredBox coloredBox() {
|
ColoredBox coloredBox() {
|
||||||
@ -30,9 +31,9 @@ void main() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect(coloredBox().color, const Color(0xff65558f));
|
expect(coloredBox().color, const Color(0xff65558f));
|
||||||
await tester.tap(find.byType(MenuAnchor));
|
await tester.tap(find.byIcon(Icons.settings));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
await tester.tap(find.widgetWithText(MenuItemButton, 'Yellow'));
|
await tester.tap(find.byType(IconButton).at(6));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(coloredBox().color, const Color(0xFF685F12));
|
expect(coloredBox().color, const Color(0xFF685F12));
|
||||||
|
@ -283,9 +283,15 @@ class ColorScheme with Diagnosticable {
|
|||||||
/// If the resulting color scheme is too dark, consider setting `dynamicSchemeVariant`
|
/// If the resulting color scheme is too dark, consider setting `dynamicSchemeVariant`
|
||||||
/// to [DynamicSchemeVariant.fidelity], whose palettes match the seed color.
|
/// to [DynamicSchemeVariant.fidelity], whose palettes match the seed color.
|
||||||
///
|
///
|
||||||
|
/// The `contrastLevel` parameter indicates the contrast level between color
|
||||||
|
/// pairs, such as [primary] and [onPrimary]. 0.0 is the default (normal);
|
||||||
|
/// -1.0 is the lowest; 1.0 is the highest. From Material Design guideline, the
|
||||||
|
/// medium and high contrast correspond to 0.5 and 1.0 respectively.
|
||||||
|
///
|
||||||
/// {@tool dartpad}
|
/// {@tool dartpad}
|
||||||
/// This sample shows how to use [ColorScheme.fromSeed] to create dynamic
|
/// This sample shows how to use [ColorScheme.fromSeed] to create dynamic
|
||||||
/// color schemes with different [DynamicSchemeVariant]s.
|
/// color schemes with different [DynamicSchemeVariant]s and different
|
||||||
|
/// contrast level.
|
||||||
///
|
///
|
||||||
/// ** See code in examples/api/lib/material/color_scheme/color_scheme.0.dart **
|
/// ** See code in examples/api/lib/material/color_scheme/color_scheme.0.dart **
|
||||||
/// {@end-tool}
|
/// {@end-tool}
|
||||||
@ -300,6 +306,7 @@ class ColorScheme with Diagnosticable {
|
|||||||
required Color seedColor,
|
required Color seedColor,
|
||||||
Brightness brightness = Brightness.light,
|
Brightness brightness = Brightness.light,
|
||||||
DynamicSchemeVariant dynamicSchemeVariant = DynamicSchemeVariant.tonalSpot,
|
DynamicSchemeVariant dynamicSchemeVariant = DynamicSchemeVariant.tonalSpot,
|
||||||
|
double contrastLevel = 0.0,
|
||||||
Color? primary,
|
Color? primary,
|
||||||
Color? onPrimary,
|
Color? onPrimary,
|
||||||
Color? primaryContainer,
|
Color? primaryContainer,
|
||||||
@ -362,7 +369,7 @@ class ColorScheme with Diagnosticable {
|
|||||||
)
|
)
|
||||||
Color? surfaceVariant,
|
Color? surfaceVariant,
|
||||||
}) {
|
}) {
|
||||||
final DynamicScheme scheme = _buildDynamicScheme(brightness, seedColor, dynamicSchemeVariant);
|
final DynamicScheme scheme = _buildDynamicScheme(brightness, seedColor, dynamicSchemeVariant, contrastLevel);
|
||||||
|
|
||||||
return ColorScheme(
|
return ColorScheme(
|
||||||
primary: primary ?? Color(MaterialDynamicColors.primary.getArgb(scheme)),
|
primary: primary ?? Color(MaterialDynamicColors.primary.getArgb(scheme)),
|
||||||
@ -688,7 +695,8 @@ class ColorScheme with Diagnosticable {
|
|||||||
/// This constructor shouldn't be used to update the Material 3 color scheme.
|
/// This constructor shouldn't be used to update the Material 3 color scheme.
|
||||||
///
|
///
|
||||||
/// For Material 3, use [ColorScheme.fromSeed] to create a color scheme
|
/// For Material 3, use [ColorScheme.fromSeed] to create a color scheme
|
||||||
/// from a single seed color based on the Material 3 color system.
|
/// from a single seed color based on the Material 3 color system. To create a
|
||||||
|
/// high-contrast color scheme, set `contrastLevel` to 1.0.
|
||||||
///
|
///
|
||||||
/// {@tool snippet}
|
/// {@tool snippet}
|
||||||
/// This example demonstrates how to create a color scheme similar to [ColorScheme.highContrastLight]
|
/// This example demonstrates how to create a color scheme similar to [ColorScheme.highContrastLight]
|
||||||
@ -819,7 +827,8 @@ class ColorScheme with Diagnosticable {
|
|||||||
/// For Material 3, use [ColorScheme.fromSeed] to create a color scheme
|
/// For Material 3, use [ColorScheme.fromSeed] to create a color scheme
|
||||||
/// from a single seed color based on the Material 3 color system.
|
/// from a single seed color based on the Material 3 color system.
|
||||||
/// Override the `brightness` property of [ColorScheme.fromSeed] to create a
|
/// Override the `brightness` property of [ColorScheme.fromSeed] to create a
|
||||||
/// dark color scheme.
|
/// dark color scheme. To create a high-contrast color scheme, set
|
||||||
|
/// `contrastLevel` to 1.0.
|
||||||
///
|
///
|
||||||
/// {@tool snippet}
|
/// {@tool snippet}
|
||||||
/// This example demonstrates how to create a color scheme similar to [ColorScheme.highContrastDark]
|
/// This example demonstrates how to create a color scheme similar to [ColorScheme.highContrastDark]
|
||||||
@ -1672,6 +1681,7 @@ class ColorScheme with Diagnosticable {
|
|||||||
required ImageProvider provider,
|
required ImageProvider provider,
|
||||||
Brightness brightness = Brightness.light,
|
Brightness brightness = Brightness.light,
|
||||||
DynamicSchemeVariant dynamicSchemeVariant = DynamicSchemeVariant.tonalSpot,
|
DynamicSchemeVariant dynamicSchemeVariant = DynamicSchemeVariant.tonalSpot,
|
||||||
|
double contrastLevel = 0.0,
|
||||||
Color? primary,
|
Color? primary,
|
||||||
Color? onPrimary,
|
Color? onPrimary,
|
||||||
Color? primaryContainer,
|
Color? primaryContainer,
|
||||||
@ -1745,7 +1755,7 @@ class ColorScheme with Diagnosticable {
|
|||||||
final List<int> scoredResults = Score.score(colorToCount, desired: 1);
|
final List<int> scoredResults = Score.score(colorToCount, desired: 1);
|
||||||
final ui.Color baseColor = Color(scoredResults.first);
|
final ui.Color baseColor = Color(scoredResults.first);
|
||||||
|
|
||||||
final DynamicScheme scheme = _buildDynamicScheme(brightness, baseColor, dynamicSchemeVariant);
|
final DynamicScheme scheme = _buildDynamicScheme(brightness, baseColor, dynamicSchemeVariant, contrastLevel);
|
||||||
|
|
||||||
return ColorScheme(
|
return ColorScheme(
|
||||||
primary: primary ?? Color(MaterialDynamicColors.primary.getArgb(scheme)),
|
primary: primary ?? Color(MaterialDynamicColors.primary.getArgb(scheme)),
|
||||||
@ -1882,19 +1892,24 @@ class ColorScheme with Diagnosticable {
|
|||||||
return (abgr & exceptRMask & exceptBMask) | (b << 16) | r;
|
return (abgr & exceptRMask & exceptBMask) | (b << 16) | r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DynamicScheme _buildDynamicScheme(Brightness brightness, Color seedColor, DynamicSchemeVariant schemeVariant) {
|
static DynamicScheme _buildDynamicScheme(
|
||||||
|
Brightness brightness,
|
||||||
|
Color seedColor,
|
||||||
|
DynamicSchemeVariant schemeVariant,
|
||||||
|
double contrastLevel,
|
||||||
|
) {
|
||||||
final bool isDark = brightness == Brightness.dark;
|
final bool isDark = brightness == Brightness.dark;
|
||||||
final Hct sourceColor = Hct.fromInt(seedColor.value);
|
final Hct sourceColor = Hct.fromInt(seedColor.value);
|
||||||
return switch (schemeVariant) {
|
return switch (schemeVariant) {
|
||||||
DynamicSchemeVariant.tonalSpot => SchemeTonalSpot(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: 0.0),
|
DynamicSchemeVariant.tonalSpot => SchemeTonalSpot(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
DynamicSchemeVariant.fidelity => SchemeFidelity(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: 0.0),
|
DynamicSchemeVariant.fidelity => SchemeFidelity(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
DynamicSchemeVariant.content => SchemeContent(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: 0.0),
|
DynamicSchemeVariant.content => SchemeContent(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
DynamicSchemeVariant.monochrome => SchemeMonochrome(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: 0.0),
|
DynamicSchemeVariant.monochrome => SchemeMonochrome(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
DynamicSchemeVariant.neutral => SchemeNeutral(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: 0.0),
|
DynamicSchemeVariant.neutral => SchemeNeutral(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
DynamicSchemeVariant.vibrant => SchemeVibrant(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: 0.0),
|
DynamicSchemeVariant.vibrant => SchemeVibrant(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
DynamicSchemeVariant.expressive => SchemeExpressive(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: 0.0),
|
DynamicSchemeVariant.expressive => SchemeExpressive(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
DynamicSchemeVariant.rainbow => SchemeRainbow(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: 0.0),
|
DynamicSchemeVariant.rainbow => SchemeRainbow(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
DynamicSchemeVariant.fruitSalad => SchemeFruitSalad(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: 0.0),
|
DynamicSchemeVariant.fruitSalad => SchemeFruitSalad(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -798,6 +798,90 @@ void main() {
|
|||||||
const Color(0xFF5D5F5F)
|
const Color(0xFF5D5F5F)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('Colors in high-contrast color scheme matches colors in DynamicScheme', (WidgetTester tester) async {
|
||||||
|
const Color seedColor = Colors.blue;
|
||||||
|
final Hct sourceColor = Hct.fromInt(seedColor.value);
|
||||||
|
|
||||||
|
void colorsMatchDynamicSchemeColors(DynamicSchemeVariant schemeVariant, Brightness brightness, double contrastLevel) {
|
||||||
|
final bool isDark = brightness == Brightness.dark;
|
||||||
|
final DynamicScheme dynamicScheme = switch (schemeVariant) {
|
||||||
|
DynamicSchemeVariant.tonalSpot => SchemeTonalSpot(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
|
DynamicSchemeVariant.fidelity => SchemeFidelity(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
|
DynamicSchemeVariant.content => SchemeContent(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
|
DynamicSchemeVariant.monochrome => SchemeMonochrome(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
|
DynamicSchemeVariant.neutral => SchemeNeutral(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
|
DynamicSchemeVariant.vibrant => SchemeVibrant(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
|
DynamicSchemeVariant.expressive => SchemeExpressive(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
|
DynamicSchemeVariant.rainbow => SchemeRainbow(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
|
DynamicSchemeVariant.fruitSalad => SchemeFruitSalad(sourceColorHct: sourceColor, isDark: isDark, contrastLevel: contrastLevel),
|
||||||
|
};
|
||||||
|
|
||||||
|
final ColorScheme colorScheme = ColorScheme.fromSeed(
|
||||||
|
seedColor: seedColor,
|
||||||
|
brightness: brightness,
|
||||||
|
dynamicSchemeVariant: schemeVariant,
|
||||||
|
contrastLevel: contrastLevel,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(colorScheme.primary.value, MaterialDynamicColors.primary.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onPrimary.value, MaterialDynamicColors.onPrimary.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.primaryContainer.value, MaterialDynamicColors.primaryContainer.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onPrimaryContainer.value, MaterialDynamicColors.onPrimaryContainer.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.primaryFixed.value, MaterialDynamicColors.primaryFixed.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.primaryFixedDim.value, MaterialDynamicColors.primaryFixedDim.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onPrimaryFixed.value, MaterialDynamicColors.onPrimaryFixed.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onPrimaryFixedVariant.value, MaterialDynamicColors.onPrimaryFixedVariant.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.secondary.value, MaterialDynamicColors.secondary.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onSecondary.value, MaterialDynamicColors.onSecondary.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.secondaryContainer.value, MaterialDynamicColors.secondaryContainer.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onSecondaryContainer.value, MaterialDynamicColors.onSecondaryContainer.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.secondaryFixed.value, MaterialDynamicColors.secondaryFixed.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.secondaryFixedDim.value, MaterialDynamicColors.secondaryFixedDim.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onSecondaryFixed.value, MaterialDynamicColors.onSecondaryFixed.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onSecondaryFixedVariant.value, MaterialDynamicColors.onSecondaryFixedVariant.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.tertiary.value, MaterialDynamicColors.tertiary.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onTertiary.value, MaterialDynamicColors.onTertiary.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.tertiaryContainer.value, MaterialDynamicColors.tertiaryContainer.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onTertiaryContainer.value, MaterialDynamicColors.onTertiaryContainer.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.tertiaryFixed.value, MaterialDynamicColors.tertiaryFixed.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.tertiaryFixedDim.value, MaterialDynamicColors.tertiaryFixedDim.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onTertiaryFixed.value, MaterialDynamicColors.onTertiaryFixed.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onTertiaryFixedVariant.value, MaterialDynamicColors.onTertiaryFixedVariant.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.error.value, MaterialDynamicColors.error.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onError.value, MaterialDynamicColors.onError.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.errorContainer.value, MaterialDynamicColors.errorContainer.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onErrorContainer.value, MaterialDynamicColors.onErrorContainer.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.background.value, MaterialDynamicColors.background.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onBackground.value, MaterialDynamicColors.onBackground.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.surface.value, MaterialDynamicColors.surface.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.surfaceDim.value, MaterialDynamicColors.surfaceDim.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.surfaceBright.value, MaterialDynamicColors.surfaceBright.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.surfaceContainerLowest.value, MaterialDynamicColors.surfaceContainerLowest.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.surfaceContainerLow.value, MaterialDynamicColors.surfaceContainerLow.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.surfaceContainer.value, MaterialDynamicColors.surfaceContainer.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.surfaceContainerHigh.value, MaterialDynamicColors.surfaceContainerHigh.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.surfaceContainerHighest.value, MaterialDynamicColors.surfaceContainerHighest.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onSurface.value, MaterialDynamicColors.onSurface.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.surfaceVariant.value, MaterialDynamicColors.surfaceVariant.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onSurfaceVariant.value, MaterialDynamicColors.onSurfaceVariant.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.outline.value, MaterialDynamicColors.outline.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.outlineVariant.value, MaterialDynamicColors.outlineVariant.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.shadow.value, MaterialDynamicColors.shadow.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.scrim.value, MaterialDynamicColors.scrim.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.inverseSurface.value, MaterialDynamicColors.inverseSurface.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.onInverseSurface.value, MaterialDynamicColors.inverseOnSurface.getArgb(dynamicScheme));
|
||||||
|
expect(colorScheme.inversePrimary.value, MaterialDynamicColors.inversePrimary.getArgb(dynamicScheme));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final DynamicSchemeVariant schemeVariant in DynamicSchemeVariant.values) {
|
||||||
|
colorsMatchDynamicSchemeColors(schemeVariant, Brightness.light, 1.0); // High contrast
|
||||||
|
colorsMatchDynamicSchemeColors(schemeVariant, Brightness.dark, 1.0);
|
||||||
|
|
||||||
|
colorsMatchDynamicSchemeColors(schemeVariant, Brightness.light, 0.5); // Medium contrast
|
||||||
|
colorsMatchDynamicSchemeColors(schemeVariant, Brightness.dark, 0.5);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _testFilledButtonColor(WidgetTester tester, ColorScheme scheme, Color expectation) async {
|
Future<void> _testFilledButtonColor(WidgetTester tester, ColorScheme scheme, Color expectation) async {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user