CupertinoDynamicColor and friends (#37719)
This commit is contained in:
parent
ffa3785411
commit
a671b28369
@ -18,6 +18,7 @@ export 'src/cupertino/colors.dart';
|
||||
export 'src/cupertino/date_picker.dart';
|
||||
export 'src/cupertino/dialog.dart';
|
||||
export 'src/cupertino/icons.dart';
|
||||
export 'src/cupertino/interface_level.dart';
|
||||
export 'src/cupertino/localizations.dart';
|
||||
export 'src/cupertino/nav_bar.dart';
|
||||
export 'src/cupertino/page_scaffold.dart';
|
||||
|
@ -8,6 +8,7 @@ import 'package:flutter/widgets.dart';
|
||||
import 'button.dart';
|
||||
import 'colors.dart';
|
||||
import 'icons.dart';
|
||||
import 'interface_level.dart';
|
||||
import 'localizations.dart';
|
||||
import 'route.dart';
|
||||
import 'theme.dart';
|
||||
@ -268,45 +269,51 @@ class _CupertinoAppState extends State<CupertinoApp> {
|
||||
|
||||
return ScrollConfiguration(
|
||||
behavior: _AlwaysCupertinoScrollBehavior(),
|
||||
child: CupertinoTheme(
|
||||
data: effectiveThemeData,
|
||||
child: WidgetsApp(
|
||||
key: GlobalObjectKey(this),
|
||||
navigatorKey: widget.navigatorKey,
|
||||
navigatorObservers: _navigatorObservers,
|
||||
pageRouteBuilder: <T>(RouteSettings settings, WidgetBuilder builder) =>
|
||||
CupertinoPageRoute<T>(settings: settings, builder: builder),
|
||||
home: widget.home,
|
||||
routes: widget.routes,
|
||||
initialRoute: widget.initialRoute,
|
||||
onGenerateRoute: widget.onGenerateRoute,
|
||||
onUnknownRoute: widget.onUnknownRoute,
|
||||
builder: widget.builder,
|
||||
title: widget.title,
|
||||
onGenerateTitle: widget.onGenerateTitle,
|
||||
textStyle: effectiveThemeData.textTheme.textStyle,
|
||||
color: widget.color ?? CupertinoColors.activeBlue,
|
||||
locale: widget.locale,
|
||||
localizationsDelegates: _localizationsDelegates,
|
||||
localeResolutionCallback: widget.localeResolutionCallback,
|
||||
localeListResolutionCallback: widget.localeListResolutionCallback,
|
||||
supportedLocales: widget.supportedLocales,
|
||||
showPerformanceOverlay: widget.showPerformanceOverlay,
|
||||
checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages,
|
||||
checkerboardOffscreenLayers: widget.checkerboardOffscreenLayers,
|
||||
showSemanticsDebugger: widget.showSemanticsDebugger,
|
||||
debugShowCheckedModeBanner: widget.debugShowCheckedModeBanner,
|
||||
inspectorSelectButtonBuilder: (BuildContext context, VoidCallback onPressed) {
|
||||
return CupertinoButton.filled(
|
||||
child: const Icon(
|
||||
CupertinoIcons.search,
|
||||
size: 28.0,
|
||||
color: CupertinoColors.white,
|
||||
),
|
||||
padding: EdgeInsets.zero,
|
||||
onPressed: onPressed,
|
||||
);
|
||||
},
|
||||
child: CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.base,
|
||||
child: CupertinoTheme(
|
||||
data: effectiveThemeData,
|
||||
child: CupertinoSystemColors(
|
||||
data: CupertinoSystemColors.of(context, useFallbackValues: true),
|
||||
child: WidgetsApp(
|
||||
key: GlobalObjectKey(this),
|
||||
navigatorKey: widget.navigatorKey,
|
||||
navigatorObservers: _navigatorObservers,
|
||||
pageRouteBuilder: <T>(RouteSettings settings, WidgetBuilder builder) =>
|
||||
CupertinoPageRoute<T>(settings: settings, builder: builder),
|
||||
home: widget.home,
|
||||
routes: widget.routes,
|
||||
initialRoute: widget.initialRoute,
|
||||
onGenerateRoute: widget.onGenerateRoute,
|
||||
onUnknownRoute: widget.onUnknownRoute,
|
||||
builder: widget.builder,
|
||||
title: widget.title,
|
||||
onGenerateTitle: widget.onGenerateTitle,
|
||||
textStyle: effectiveThemeData.textTheme.textStyle,
|
||||
color: widget.color ?? CupertinoColors.activeBlue,
|
||||
locale: widget.locale,
|
||||
localizationsDelegates: _localizationsDelegates,
|
||||
localeResolutionCallback: widget.localeResolutionCallback,
|
||||
localeListResolutionCallback: widget.localeListResolutionCallback,
|
||||
supportedLocales: widget.supportedLocales,
|
||||
showPerformanceOverlay: widget.showPerformanceOverlay,
|
||||
checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages,
|
||||
checkerboardOffscreenLayers: widget.checkerboardOffscreenLayers,
|
||||
showSemanticsDebugger: widget.showSemanticsDebugger,
|
||||
debugShowCheckedModeBanner: widget.debugShowCheckedModeBanner,
|
||||
inspectorSelectButtonBuilder: (BuildContext context, VoidCallback onPressed) {
|
||||
return CupertinoButton.filled(
|
||||
child: const Icon(
|
||||
CupertinoIcons.search,
|
||||
size: 28.0,
|
||||
color: CupertinoColors.white,
|
||||
),
|
||||
padding: EdgeInsets.zero,
|
||||
onPressed: onPressed,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
File diff suppressed because it is too large
Load Diff
76
packages/flutter/lib/src/cupertino/interface_level.dart
Normal file
76
packages/flutter/lib/src/cupertino/interface_level.dart
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import '../widgets/framework.dart';
|
||||
|
||||
/// Indicates the visual level for a piece of content. Equivalent to `UIUserInterfaceLevel`
|
||||
/// from `UIKit`.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * `UIUserInterfaceLevel`, the UIKit equivalent: https://developer.apple.com/documentation/uikit/uiuserinterfacelevel.
|
||||
enum CupertinoUserInterfaceLevelData {
|
||||
/// The level for your window's main content.
|
||||
base,
|
||||
|
||||
/// The level for content visually above [base].
|
||||
elevated,
|
||||
}
|
||||
|
||||
/// Establishes a subtree in which [CupertinoUserInterfaceLevel.of] resolves to
|
||||
/// the given data.
|
||||
///
|
||||
/// Querying the current elevation status using [CupertinoUserInterfaceLevel.of]
|
||||
/// will cause your widget to rebuild automatically whenever the [CupertinoUserInterfaceLevelData]
|
||||
/// changes.
|
||||
///
|
||||
/// If no [CupertinoUserInterfaceLevel] is in scope then the [CupertinoUserInterfaceLevel.of]
|
||||
/// method will throw an exception, unless the `nullOk` argument is set to true,
|
||||
/// in which case it returns null.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [CupertinoUserInterfaceLevelData], specifies the visual level for the content
|
||||
/// in the subtree [CupertinoUserInterfaceLevel] established.
|
||||
class CupertinoUserInterfaceLevel extends InheritedWidget {
|
||||
/// Creates a [CupertinoUserInterfaceLevel] to change descendant Cupertino widget's
|
||||
/// visual level.
|
||||
const CupertinoUserInterfaceLevel({
|
||||
Key key,
|
||||
@required CupertinoUserInterfaceLevelData data,
|
||||
Widget child,
|
||||
}) : assert(data != null),
|
||||
_data = data,
|
||||
super(key: key, child: child);
|
||||
|
||||
final CupertinoUserInterfaceLevelData _data;
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(CupertinoUserInterfaceLevel oldWidget) => oldWidget._data != _data;
|
||||
|
||||
/// The data from the closest instance of this class that encloses the given
|
||||
/// context.
|
||||
///
|
||||
/// You can use this function to query the user interface elevation level within
|
||||
/// the given [BuildContext]. When that information changes, your widget will
|
||||
/// be scheduled to be rebuilt, keeping your widget up-to-date.
|
||||
static CupertinoUserInterfaceLevelData of(BuildContext context, { bool nullOk = false }) {
|
||||
assert(context != null);
|
||||
assert(nullOk != null);
|
||||
final CupertinoUserInterfaceLevel query = context.inheritFromWidgetOfExactType(CupertinoUserInterfaceLevel);
|
||||
if (query != null)
|
||||
return query._data;
|
||||
if (nullOk)
|
||||
return null;
|
||||
throw FlutterError(
|
||||
'CupertinoUserInterfaceLevel.of() called with a context that does not contain a CupertinoUserInterfaceLevel.\n'
|
||||
'No CupertinoUserInterfaceLevel ancestor could be found starting from the context that was passed '
|
||||
'to CupertinoUserInterfaceLevel.of(). This can happen because you do not have a WidgetsApp or '
|
||||
'MaterialApp widget (those widgets introduce a CupertinoUserInterfaceLevel), or it can happen '
|
||||
'if the context you use comes from a widget above those widgets.\n'
|
||||
'The context used was:\n'
|
||||
' $context'
|
||||
);
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'colors.dart';
|
||||
import 'theme.dart';
|
||||
import 'thumb_painter.dart';
|
||||
|
||||
@ -228,7 +229,10 @@ class _CupertinoSliderState extends State<CupertinoSlider> with TickerProviderSt
|
||||
return _CupertinoSliderRenderObjectWidget(
|
||||
value: (widget.value - widget.min) / (widget.max - widget.min),
|
||||
divisions: widget.divisions,
|
||||
activeColor: widget.activeColor ?? CupertinoTheme.of(context).primaryColor,
|
||||
activeColor: CupertinoDynamicColor.resolve(
|
||||
widget.activeColor ?? CupertinoTheme.of(context).primaryColor,
|
||||
context
|
||||
),
|
||||
onChanged: widget.onChanged != null ? _handleChanged : null,
|
||||
onChangeStart: widget.onChangeStart != null ? _handleDragStart : null,
|
||||
onChangeEnd: widget.onChangeEnd != null ? _handleDragEnd : null,
|
||||
@ -257,12 +261,14 @@ class _CupertinoSliderRenderObjectWidget extends LeafRenderObjectWidget {
|
||||
final ValueChanged<double> onChangeEnd;
|
||||
final TickerProvider vsync;
|
||||
|
||||
|
||||
@override
|
||||
_RenderCupertinoSlider createRenderObject(BuildContext context) {
|
||||
return _RenderCupertinoSlider(
|
||||
value: value,
|
||||
divisions: divisions,
|
||||
activeColor: activeColor,
|
||||
trackColor: CupertinoDynamicColor.resolve(CupertinoSystemColors.of(context).systemFill, context),
|
||||
onChanged: onChanged,
|
||||
onChangeStart: onChangeStart,
|
||||
onChangeEnd: onChangeEnd,
|
||||
@ -277,6 +283,7 @@ class _CupertinoSliderRenderObjectWidget extends LeafRenderObjectWidget {
|
||||
..value = value
|
||||
..divisions = divisions
|
||||
..activeColor = activeColor
|
||||
..trackColor = CupertinoDynamicColor.resolve(CupertinoSystemColors.of(context).systemFill, context)
|
||||
..onChanged = onChanged
|
||||
..onChangeStart = onChangeStart
|
||||
..onChangeEnd = onChangeEnd
|
||||
@ -287,7 +294,6 @@ class _CupertinoSliderRenderObjectWidget extends LeafRenderObjectWidget {
|
||||
}
|
||||
|
||||
const double _kPadding = 8.0;
|
||||
const Color _kTrackColor = Color(0xFFB5B5B5);
|
||||
const double _kSliderHeight = 2.0 * (CupertinoThumbPainter.radius + _kPadding);
|
||||
const double _kSliderWidth = 176.0; // Matches Material Design slider.
|
||||
const Duration _kDiscreteTransitionDuration = Duration(milliseconds: 500);
|
||||
@ -299,6 +305,7 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
|
||||
@required double value,
|
||||
int divisions,
|
||||
Color activeColor,
|
||||
Color trackColor,
|
||||
ValueChanged<double> onChanged,
|
||||
this.onChangeStart,
|
||||
this.onChangeEnd,
|
||||
@ -309,6 +316,7 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
|
||||
_value = value,
|
||||
_divisions = divisions,
|
||||
_activeColor = activeColor,
|
||||
_trackColor = trackColor,
|
||||
_onChanged = onChanged,
|
||||
_textDirection = textDirection,
|
||||
super(additionalConstraints: const BoxConstraints.tightFor(width: _kSliderWidth, height: _kSliderHeight)) {
|
||||
@ -355,6 +363,15 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
|
||||
markNeedsPaint();
|
||||
}
|
||||
|
||||
Color get trackColor => _trackColor;
|
||||
Color _trackColor;
|
||||
set trackColor(Color value) {
|
||||
if (value == _trackColor)
|
||||
return;
|
||||
_trackColor = value;
|
||||
markNeedsPaint();
|
||||
}
|
||||
|
||||
ValueChanged<double> get onChanged => _onChanged;
|
||||
ValueChanged<double> _onChanged;
|
||||
set onChanged(ValueChanged<double> value) {
|
||||
@ -468,11 +485,11 @@ class _RenderCupertinoSlider extends RenderConstrainedBox {
|
||||
case TextDirection.rtl:
|
||||
visualPosition = 1.0 - _position.value;
|
||||
leftColor = _activeColor;
|
||||
rightColor = _kTrackColor;
|
||||
rightColor = trackColor;
|
||||
break;
|
||||
case TextDirection.ltr:
|
||||
visualPosition = _position.value;
|
||||
leftColor = _kTrackColor;
|
||||
leftColor = trackColor;
|
||||
rightColor = _activeColor;
|
||||
break;
|
||||
}
|
||||
|
@ -213,6 +213,32 @@ class CupertinoTextThemeData extends Diagnosticable {
|
||||
(_isLight ? _kDefaultDateTimePickerLightTextStyle : _kDefaultDateTimePickerDarkTextStyle);
|
||||
}
|
||||
|
||||
/// Returns a copy of the current [CupertinoTextThemeData] with all the colors
|
||||
/// resolved against the given [BuildContext].
|
||||
CupertinoTextThemeData resolveFrom(BuildContext context, { bool nullOk = false }) {
|
||||
Color convertColor(Color color) => color == null ? null : CupertinoDynamicColor.resolve(color, context, nullOk: nullOk);
|
||||
|
||||
TextStyle resolveTextStyle(TextStyle textStyle) {
|
||||
return textStyle?.copyWith(
|
||||
color: convertColor(textStyle.color),
|
||||
backgroundColor: convertColor(textStyle.backgroundColor),
|
||||
decorationColor: convertColor(textStyle.decorationColor),
|
||||
);
|
||||
}
|
||||
|
||||
return copyWith(
|
||||
primaryColor: convertColor(_primaryColor),
|
||||
textStyle: resolveTextStyle(_textStyle),
|
||||
actionTextStyle: resolveTextStyle(_actionTextStyle),
|
||||
tabLabelTextStyle: resolveTextStyle(_tabLabelTextStyle),
|
||||
navTitleTextStyle : resolveTextStyle(_navTitleTextStyle),
|
||||
navLargeTitleTextStyle: resolveTextStyle(_navLargeTitleTextStyle),
|
||||
navActionTextStyle: resolveTextStyle(_navActionTextStyle),
|
||||
pickerTextStyle: resolveTextStyle(_pickerTextStyle),
|
||||
dateTimePickerTextStyle: resolveTextStyle(_dateTimePickerTextStyle),
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns a copy of the current [CupertinoTextThemeData] instance with
|
||||
/// specified overrides.
|
||||
CupertinoTextThemeData copyWith({
|
||||
|
@ -54,7 +54,20 @@ class CupertinoTheme extends StatelessWidget {
|
||||
/// exist in the ancestry tree.
|
||||
static CupertinoThemeData of(BuildContext context) {
|
||||
final _InheritedCupertinoTheme inheritedTheme = context.inheritFromWidgetOfExactType(_InheritedCupertinoTheme);
|
||||
return inheritedTheme?.theme?.data ?? const CupertinoThemeData();
|
||||
return (inheritedTheme?.theme?.data ?? const CupertinoThemeData()).resolveFrom(context, nullOk: true);
|
||||
}
|
||||
|
||||
/// Retrieve the [Brightness] value from the closest ancestor [CupertinoTheme]
|
||||
/// widget.
|
||||
///
|
||||
/// If no ancestral [CupertinoTheme] widget with explicit brightness value could
|
||||
/// be found, the method will resort to the closest ancestor [MediaQuery] widget.
|
||||
///
|
||||
/// Throws an exception if no such [CupertinoTheme] or [MediaQuery] widgets exist
|
||||
/// in the ancestry tree, unless [nullOk] is set to true.
|
||||
static Brightness brightnessOf(BuildContext context, { bool nullOk = false }) {
|
||||
final _InheritedCupertinoTheme inheritedTheme = context.inheritFromWidgetOfExactType(_InheritedCupertinoTheme);
|
||||
return inheritedTheme?.theme?.data?._brightness ?? MediaQuery.of(context, nullOk: nullOk)?.platformBrightness;
|
||||
}
|
||||
|
||||
/// The widget below this widget in the tree.
|
||||
@ -229,6 +242,23 @@ class CupertinoThemeData extends Diagnosticable {
|
||||
);
|
||||
}
|
||||
|
||||
/// Return a new `CupertinoThemeData` whose colors are from this `CupertinoThemeData`,
|
||||
/// but resolved aginst the given [BuildContext].
|
||||
///
|
||||
/// It will be called in [CupertinoTheme.of].
|
||||
@protected
|
||||
CupertinoThemeData resolveFrom(BuildContext context, { bool nullOk = false }) {
|
||||
Color convertColor(Color color) => color == null ? null : CupertinoDynamicColor.resolve(color, context, nullOk: nullOk);
|
||||
|
||||
return copyWith(
|
||||
primaryColor: convertColor(primaryColor),
|
||||
primaryContrastingColor: convertColor(primaryContrastingColor),
|
||||
textTheme: textTheme?.resolveFrom(context, nullOk: nullOk),
|
||||
barBackgroundColor: convertColor(barBackgroundColor),
|
||||
scaffoldBackgroundColor: convertColor(scaffoldBackgroundColor),
|
||||
);
|
||||
}
|
||||
|
||||
/// Create a copy of [CupertinoThemeData] with specified attributes overridden.
|
||||
///
|
||||
/// Only the current instance's specified attributes are copied instead of
|
||||
@ -296,4 +326,39 @@ class _NoDefaultCupertinoThemeData extends CupertinoThemeData {
|
||||
final Color barBackgroundColor;
|
||||
@override
|
||||
final Color scaffoldBackgroundColor;
|
||||
|
||||
@override
|
||||
_NoDefaultCupertinoThemeData resolveFrom(BuildContext context, { bool nullOk = false }) {
|
||||
Color convertColor(Color color) => color == null
|
||||
? null
|
||||
: CupertinoDynamicColor.resolve(color, context, nullOk: nullOk);
|
||||
|
||||
return _NoDefaultCupertinoThemeData(
|
||||
brightness,
|
||||
convertColor(primaryColor),
|
||||
convertColor(primaryContrastingColor),
|
||||
textTheme?.resolveFrom(context, nullOk: nullOk),
|
||||
convertColor(barBackgroundColor),
|
||||
convertColor(scaffoldBackgroundColor),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
CupertinoThemeData copyWith({
|
||||
Brightness brightness,
|
||||
Color primaryColor,
|
||||
Color primaryContrastingColor,
|
||||
CupertinoTextThemeData textTheme,
|
||||
Color barBackgroundColor ,
|
||||
Color scaffoldBackgroundColor
|
||||
}) {
|
||||
return _NoDefaultCupertinoThemeData(
|
||||
brightness ?? this.brightness,
|
||||
primaryColor ?? this.primaryColor,
|
||||
primaryContrastingColor ?? this.primaryContrastingColor,
|
||||
textTheme ?? this.textTheme,
|
||||
barBackgroundColor ?? this.barBackgroundColor,
|
||||
scaffoldBackgroundColor ?? this.scaffoldBackgroundColor,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1416,34 +1416,43 @@ class MaterialBasedCupertinoThemeData extends CupertinoThemeData {
|
||||
///
|
||||
/// The [materialTheme] parameter must not be null.
|
||||
MaterialBasedCupertinoThemeData({
|
||||
@required ThemeData materialTheme,
|
||||
}) : assert(materialTheme != null),
|
||||
_materialTheme = materialTheme,
|
||||
// Pass all values to the superclass so Material-agnostic properties
|
||||
// like barBackgroundColor can still behave like a normal
|
||||
// CupertinoThemeData.
|
||||
super.raw(
|
||||
materialTheme.cupertinoOverrideTheme?.brightness,
|
||||
materialTheme.cupertinoOverrideTheme?.primaryColor,
|
||||
materialTheme.cupertinoOverrideTheme?.primaryContrastingColor,
|
||||
materialTheme.cupertinoOverrideTheme?.textTheme,
|
||||
materialTheme.cupertinoOverrideTheme?.barBackgroundColor,
|
||||
materialTheme.cupertinoOverrideTheme?.scaffoldBackgroundColor,
|
||||
);
|
||||
@required ThemeData materialTheme,
|
||||
}) : this._(
|
||||
materialTheme,
|
||||
(materialTheme.cupertinoOverrideTheme ?? const CupertinoThemeData()).noDefault(),
|
||||
);
|
||||
|
||||
MaterialBasedCupertinoThemeData._(
|
||||
this._materialTheme,
|
||||
this._cupertinoOverrideTheme,
|
||||
) : assert(_materialTheme != null),
|
||||
assert(_cupertinoOverrideTheme != null),
|
||||
// Pass all values to the superclass so Material-agnostic properties
|
||||
// like barBackgroundColor can still behave like a normal
|
||||
// CupertinoThemeData.
|
||||
super.raw(
|
||||
_cupertinoOverrideTheme.brightness,
|
||||
_cupertinoOverrideTheme.primaryColor,
|
||||
_cupertinoOverrideTheme.primaryContrastingColor,
|
||||
_cupertinoOverrideTheme.textTheme,
|
||||
_cupertinoOverrideTheme.barBackgroundColor,
|
||||
_cupertinoOverrideTheme.scaffoldBackgroundColor,
|
||||
);
|
||||
|
||||
final ThemeData _materialTheme;
|
||||
final CupertinoThemeData _cupertinoOverrideTheme;
|
||||
|
||||
@override
|
||||
Brightness get brightness => _materialTheme.cupertinoOverrideTheme?.brightness ?? _materialTheme.brightness;
|
||||
Brightness get brightness => _cupertinoOverrideTheme.brightness ?? _materialTheme.brightness;
|
||||
|
||||
@override
|
||||
Color get primaryColor => _materialTheme.cupertinoOverrideTheme?.primaryColor ?? _materialTheme.colorScheme.primary;
|
||||
Color get primaryColor => _cupertinoOverrideTheme.primaryColor ?? _materialTheme.colorScheme.primary;
|
||||
|
||||
@override
|
||||
Color get primaryContrastingColor => _materialTheme.cupertinoOverrideTheme?.primaryContrastingColor ?? _materialTheme.colorScheme.onPrimary;
|
||||
Color get primaryContrastingColor => _cupertinoOverrideTheme.primaryContrastingColor ?? _materialTheme.colorScheme.onPrimary;
|
||||
|
||||
@override
|
||||
Color get scaffoldBackgroundColor => _materialTheme.cupertinoOverrideTheme?.scaffoldBackgroundColor ?? _materialTheme.scaffoldBackgroundColor;
|
||||
Color get scaffoldBackgroundColor => _cupertinoOverrideTheme.scaffoldBackgroundColor ?? _materialTheme.scaffoldBackgroundColor;
|
||||
|
||||
/// Copies the [ThemeData]'s `cupertinoOverrideTheme`.
|
||||
///
|
||||
@ -1457,7 +1466,7 @@ class MaterialBasedCupertinoThemeData extends CupertinoThemeData {
|
||||
/// new Material [Theme] and use `copyWith` on the Material [ThemeData]
|
||||
/// instead.
|
||||
@override
|
||||
CupertinoThemeData copyWith({
|
||||
MaterialBasedCupertinoThemeData copyWith({
|
||||
Brightness brightness,
|
||||
Color primaryColor,
|
||||
Color primaryContrastingColor,
|
||||
@ -1465,20 +1474,26 @@ class MaterialBasedCupertinoThemeData extends CupertinoThemeData {
|
||||
Color barBackgroundColor,
|
||||
Color scaffoldBackgroundColor,
|
||||
}) {
|
||||
return _materialTheme.cupertinoOverrideTheme?.copyWith(
|
||||
brightness: brightness,
|
||||
primaryColor: primaryColor,
|
||||
primaryContrastingColor: primaryContrastingColor,
|
||||
textTheme: textTheme,
|
||||
barBackgroundColor: barBackgroundColor,
|
||||
scaffoldBackgroundColor: scaffoldBackgroundColor,
|
||||
) ?? CupertinoThemeData(
|
||||
brightness: brightness,
|
||||
primaryColor: primaryColor,
|
||||
primaryContrastingColor: primaryContrastingColor,
|
||||
textTheme: textTheme,
|
||||
barBackgroundColor: barBackgroundColor,
|
||||
scaffoldBackgroundColor: scaffoldBackgroundColor,
|
||||
return MaterialBasedCupertinoThemeData._(
|
||||
_materialTheme,
|
||||
_cupertinoOverrideTheme.copyWith(
|
||||
brightness: brightness,
|
||||
primaryColor: primaryColor,
|
||||
primaryContrastingColor: primaryContrastingColor,
|
||||
textTheme: textTheme,
|
||||
barBackgroundColor: barBackgroundColor,
|
||||
scaffoldBackgroundColor: scaffoldBackgroundColor,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
CupertinoThemeData resolveFrom(BuildContext context, { bool nullOk = false }) {
|
||||
// Only the cupertino override theme part will be resolved.
|
||||
// If the color comes from the material theme it's not resolved.
|
||||
return MaterialBasedCupertinoThemeData._(
|
||||
_materialTheme,
|
||||
_cupertinoOverrideTheme.resolveFrom(context, nullOk: nullOk),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,7 @@ class MediaQueryData {
|
||||
this.alwaysUse24HourFormat = false,
|
||||
this.accessibleNavigation = false,
|
||||
this.invertColors = false,
|
||||
this.highContrast = false,
|
||||
this.disableAnimations = false,
|
||||
this.boldText = false,
|
||||
});
|
||||
@ -121,6 +122,7 @@ class MediaQueryData {
|
||||
invertColors = window.accessibilityFeatures.invertColors,
|
||||
disableAnimations = window.accessibilityFeatures.disableAnimations,
|
||||
boldText = window.accessibilityFeatures.boldText,
|
||||
highContrast = false,
|
||||
alwaysUse24HourFormat = window.alwaysUse24HourFormat;
|
||||
|
||||
/// The size of the media in logical pixels (e.g, the size of the screen).
|
||||
@ -259,6 +261,13 @@ class MediaQueryData {
|
||||
/// * [Window.AccessibilityFeatures], where the setting originates.
|
||||
final bool invertColors;
|
||||
|
||||
/// Whether the user requested a high contrast between foreground and background
|
||||
/// content on iOS, via Settings -> Accessibility -> Increase Contrast.
|
||||
///
|
||||
/// This flag is currently only updated on iOS devices that are running iOS 13
|
||||
/// or above.
|
||||
final bool highContrast;
|
||||
|
||||
/// Whether the platform is requesting that animations be disabled or reduced
|
||||
/// as much as possible.
|
||||
///
|
||||
@ -293,6 +302,7 @@ class MediaQueryData {
|
||||
EdgeInsets viewInsets,
|
||||
double physicalDepth,
|
||||
bool alwaysUse24HourFormat,
|
||||
bool highContrast,
|
||||
bool disableAnimations,
|
||||
bool invertColors,
|
||||
bool accessibleNavigation,
|
||||
@ -309,6 +319,7 @@ class MediaQueryData {
|
||||
physicalDepth: physicalDepth ?? this.physicalDepth,
|
||||
alwaysUse24HourFormat: alwaysUse24HourFormat ?? this.alwaysUse24HourFormat,
|
||||
invertColors: invertColors ?? this.invertColors,
|
||||
highContrast: highContrast ?? this.highContrast,
|
||||
disableAnimations: disableAnimations ?? this.disableAnimations,
|
||||
accessibleNavigation: accessibleNavigation ?? this.accessibleNavigation,
|
||||
boldText: boldText ?? this.boldText,
|
||||
@ -357,6 +368,7 @@ class MediaQueryData {
|
||||
),
|
||||
viewInsets: viewInsets,
|
||||
alwaysUse24HourFormat: alwaysUse24HourFormat,
|
||||
highContrast: highContrast,
|
||||
disableAnimations: disableAnimations,
|
||||
invertColors: invertColors,
|
||||
accessibleNavigation: accessibleNavigation,
|
||||
@ -404,6 +416,7 @@ class MediaQueryData {
|
||||
bottom: removeBottom ? 0.0 : null,
|
||||
),
|
||||
alwaysUse24HourFormat: alwaysUse24HourFormat,
|
||||
highContrast: highContrast,
|
||||
disableAnimations: disableAnimations,
|
||||
invertColors: invertColors,
|
||||
accessibleNavigation: accessibleNavigation,
|
||||
@ -451,6 +464,7 @@ class MediaQueryData {
|
||||
bottom: removeBottom ? 0.0 : null,
|
||||
),
|
||||
alwaysUse24HourFormat: alwaysUse24HourFormat,
|
||||
highContrast: highContrast,
|
||||
disableAnimations: disableAnimations,
|
||||
invertColors: invertColors,
|
||||
accessibleNavigation: accessibleNavigation,
|
||||
@ -472,6 +486,7 @@ class MediaQueryData {
|
||||
&& typedOther.viewInsets == viewInsets
|
||||
&& typedOther.physicalDepth == physicalDepth
|
||||
&& typedOther.alwaysUse24HourFormat == alwaysUse24HourFormat
|
||||
&& typedOther.highContrast == highContrast
|
||||
&& typedOther.disableAnimations == disableAnimations
|
||||
&& typedOther.invertColors == invertColors
|
||||
&& typedOther.accessibleNavigation == accessibleNavigation
|
||||
@ -490,6 +505,7 @@ class MediaQueryData {
|
||||
viewInsets,
|
||||
physicalDepth,
|
||||
alwaysUse24HourFormat,
|
||||
highContrast,
|
||||
disableAnimations,
|
||||
invertColors,
|
||||
accessibleNavigation,
|
||||
@ -510,6 +526,7 @@ class MediaQueryData {
|
||||
'physicalDepth: $physicalDepth, '
|
||||
'alwaysUse24HourFormat: $alwaysUse24HourFormat, '
|
||||
'accessibleNavigation: $accessibleNavigation, '
|
||||
'highContrast: $highContrast,'
|
||||
'disableAnimations: $disableAnimations, '
|
||||
'invertColors: $invertColors, '
|
||||
'boldText: $boldText'
|
||||
|
748
packages/flutter/test/cupertino/colors_test.dart
Normal file
748
packages/flutter/test/cupertino/colors_test.dart
Normal file
@ -0,0 +1,748 @@
|
||||
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
|
||||
import '../rendering/mock_canvas.dart';
|
||||
|
||||
class DependentWidget extends StatelessWidget {
|
||||
const DependentWidget({
|
||||
Key key,
|
||||
this.color
|
||||
}) : super(key: key);
|
||||
|
||||
final Color color;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final Color resolved = CupertinoDynamicColor.resolve(color, context);
|
||||
return DecoratedBox(
|
||||
decoration: BoxDecoration(color: resolved),
|
||||
child: const SizedBox.expand(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const Color color0 = Color(0xFF000000);
|
||||
const Color color1 = Color(0xFF000001);
|
||||
const Color color2 = Color(0xFF000002);
|
||||
const Color color3 = Color(0xFF000003);
|
||||
const Color color4 = Color(0xFF000004);
|
||||
const Color color5 = Color(0xFF000005);
|
||||
const Color color6 = Color(0xFF000006);
|
||||
const Color color7 = Color(0xFF000007);
|
||||
|
||||
// A color that depends on color vibrancy, accessibility contrast, as well as user
|
||||
// interface elevation.
|
||||
final CupertinoDynamicColor dynamicColor = CupertinoDynamicColor(
|
||||
color: color0,
|
||||
darkColor: color1,
|
||||
elevatedColor: color2,
|
||||
highContrastColor: color3,
|
||||
darkElevatedColor: color4,
|
||||
darkHighContrastColor: color5,
|
||||
highContrastElevatedColor: color6,
|
||||
darkHighContrastElevatedColor: color7,
|
||||
);
|
||||
|
||||
// A color that uses [color0] in every circumstance.
|
||||
final Color notSoDynamicColor1 = CupertinoDynamicColor(
|
||||
color: color0,
|
||||
darkColor: color0,
|
||||
darkHighContrastColor: color0,
|
||||
darkElevatedColor: color0,
|
||||
darkHighContrastElevatedColor: color0,
|
||||
highContrastColor: color0,
|
||||
highContrastElevatedColor: color0,
|
||||
elevatedColor: color0,
|
||||
);
|
||||
|
||||
// A color that uses [color1] for light mode, and [color0] for dark mode.
|
||||
final Color vibrancyDependentColor1 = CupertinoDynamicColor(
|
||||
color: color1,
|
||||
elevatedColor: color1,
|
||||
highContrastColor: color1,
|
||||
highContrastElevatedColor: color1,
|
||||
darkColor: color0,
|
||||
darkHighContrastColor: color0,
|
||||
darkElevatedColor: color0,
|
||||
darkHighContrastElevatedColor: color0,
|
||||
);
|
||||
|
||||
// A color that uses [color1] for normal contrast mode, and [color0] for high
|
||||
// contrast mode.
|
||||
final Color contrastDependentColor1 = CupertinoDynamicColor(
|
||||
color: color1,
|
||||
darkColor: color1,
|
||||
elevatedColor: color1,
|
||||
darkElevatedColor: color1,
|
||||
highContrastColor: color0,
|
||||
darkHighContrastColor: color0,
|
||||
highContrastElevatedColor: color0,
|
||||
darkHighContrastElevatedColor: color0,
|
||||
);
|
||||
|
||||
// A color that uses [color1] for base interface elevation, and [color0] for elevated
|
||||
// interface elevation.
|
||||
final Color elevationDependentColor1 = CupertinoDynamicColor(
|
||||
color: color1,
|
||||
darkColor: color1,
|
||||
highContrastColor: color1,
|
||||
darkHighContrastColor: color1,
|
||||
elevatedColor: color0,
|
||||
darkElevatedColor: color0,
|
||||
highContrastElevatedColor: color0,
|
||||
darkHighContrastElevatedColor: color0,
|
||||
);
|
||||
|
||||
void main() {
|
||||
test('== works as expected', () {
|
||||
expect(dynamicColor, CupertinoDynamicColor(
|
||||
color: color0,
|
||||
darkColor: color1,
|
||||
elevatedColor: color2,
|
||||
highContrastColor: color3,
|
||||
darkElevatedColor: color4,
|
||||
darkHighContrastColor: color5,
|
||||
highContrastElevatedColor: color6,
|
||||
darkHighContrastElevatedColor: color7,
|
||||
)
|
||||
);
|
||||
|
||||
expect(notSoDynamicColor1, isNot(vibrancyDependentColor1));
|
||||
|
||||
expect(notSoDynamicColor1, isNot(contrastDependentColor1));
|
||||
|
||||
expect(vibrancyDependentColor1, isNot(CupertinoDynamicColor(
|
||||
color: color0,
|
||||
elevatedColor: color0,
|
||||
highContrastColor: color0,
|
||||
highContrastElevatedColor: color0,
|
||||
darkColor: color0,
|
||||
darkHighContrastColor: color0,
|
||||
darkElevatedColor: color0,
|
||||
darkHighContrastElevatedColor: color0,
|
||||
)));
|
||||
});
|
||||
|
||||
test('CupertinoDynamicColor.toString() works', () {
|
||||
expect(
|
||||
dynamicColor.toString(),
|
||||
'CupertinoDynamicColor(*color = Color(0xff000000)*, '
|
||||
'darkColor = Color(0xff000001), '
|
||||
'highContrastColor = Color(0xff000003), '
|
||||
'darkHighContrastColor = Color(0xff000005), '
|
||||
'elevatedColor = Color(0xff000002), '
|
||||
'darkElevatedColor = Color(0xff000004), '
|
||||
'highContrastElevatedColor = Color(0xff000006), '
|
||||
'darkHighContrastElevatedColor = Color(0xff000007))'
|
||||
);
|
||||
expect(notSoDynamicColor1.toString(), 'CupertinoDynamicColor(*color = Color(0xff000000)*)');
|
||||
expect(vibrancyDependentColor1.toString(), 'CupertinoDynamicColor(*color = Color(0xff000001)*, darkColor = Color(0xff000000))');
|
||||
expect(contrastDependentColor1.toString(), 'CupertinoDynamicColor(*color = Color(0xff000001)*, highContrastColor = Color(0xff000000))');
|
||||
expect(elevationDependentColor1.toString(), 'CupertinoDynamicColor(*color = Color(0xff000001)*, elevatedColor = Color(0xff000000))');
|
||||
|
||||
expect(
|
||||
CupertinoDynamicColor.withBrightnessAndContrast(
|
||||
color: color0,
|
||||
darkColor: color1,
|
||||
highContrastColor: color2,
|
||||
darkHighContrastColor: color3,
|
||||
).toString(),
|
||||
'CupertinoDynamicColor(*color = Color(0xff000000)*, '
|
||||
'darkColor = Color(0xff000001), '
|
||||
'highContrastColor = Color(0xff000002), '
|
||||
'darkHighContrastColor = Color(0xff000003))',
|
||||
);
|
||||
});
|
||||
|
||||
test('withVibrancy constructor creates colors that may depend on vibrancy', () {
|
||||
expect(vibrancyDependentColor1, CupertinoDynamicColor.withBrightness(
|
||||
color: color1,
|
||||
darkColor: color0,
|
||||
));
|
||||
});
|
||||
|
||||
test('withVibrancyAndContrast constructor creates colors that may depend on contrast and vibrancy', () {
|
||||
expect(contrastDependentColor1, CupertinoDynamicColor.withBrightnessAndContrast(
|
||||
color: color1,
|
||||
darkColor: color1,
|
||||
highContrastColor: color0,
|
||||
darkHighContrastColor: color0,
|
||||
));
|
||||
|
||||
expect(CupertinoDynamicColor(
|
||||
color: color0,
|
||||
darkColor: color1,
|
||||
highContrastColor: color2,
|
||||
darkHighContrastColor: color3,
|
||||
elevatedColor: color0,
|
||||
darkElevatedColor: color1,
|
||||
highContrastElevatedColor: color2,
|
||||
darkHighContrastElevatedColor: color3,
|
||||
),
|
||||
CupertinoDynamicColor.withBrightnessAndContrast(
|
||||
color: color0,
|
||||
darkColor: color1,
|
||||
highContrastColor: color2,
|
||||
darkHighContrastColor: color3,
|
||||
));
|
||||
});
|
||||
|
||||
testWidgets('Dynamic colors that are not actually dynamic should not claim dependencies',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(DependentWidget(color: notSoDynamicColor1));
|
||||
|
||||
expect(tester.takeException(), null);
|
||||
expect(find.byType(DependentWidget), paints..rect(color: color0));
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'Dynamic colors that are only dependent on vibrancy should not claim unnecessary dependencies, '
|
||||
'and its resolved color should change when its dependency changes',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.light),
|
||||
child: DependentWidget(color: vibrancyDependentColor1),
|
||||
),
|
||||
);
|
||||
|
||||
expect(tester.takeException(), null);
|
||||
expect(find.byType(DependentWidget), paints..rect(color: color1));
|
||||
expect(find.byType(DependentWidget), isNot(paints..rect(color: color0)));
|
||||
|
||||
// Changing color vibrancy works.
|
||||
await tester.pumpWidget(
|
||||
MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.dark),
|
||||
child: DependentWidget(color: vibrancyDependentColor1),
|
||||
),
|
||||
);
|
||||
|
||||
expect(tester.takeException(), null);
|
||||
expect(find.byType(DependentWidget), paints..rect(color: color0));
|
||||
expect(find.byType(DependentWidget), isNot(paints..rect(color: color1)));
|
||||
|
||||
// CupertinoTheme should take percedence over MediaQuery.
|
||||
await tester.pumpWidget(
|
||||
CupertinoTheme(
|
||||
data: const CupertinoThemeData(brightness: Brightness.light),
|
||||
child: MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.dark),
|
||||
child: DependentWidget(color: vibrancyDependentColor1),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(tester.takeException(), null);
|
||||
expect(find.byType(DependentWidget), paints..rect(color: color1));
|
||||
expect(find.byType(DependentWidget), isNot(paints..rect(color: color0)));
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'Dynamic colors that are only dependent on accessibility contrast should not claim unnecessary dependencies, '
|
||||
'and its resolved color should change when its dependency changes',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MediaQuery(
|
||||
data: const MediaQueryData(highContrast: false),
|
||||
child: DependentWidget(color: contrastDependentColor1),
|
||||
),
|
||||
);
|
||||
|
||||
expect(tester.takeException(), null);
|
||||
expect(find.byType(DependentWidget), paints..rect(color: color1));
|
||||
expect(find.byType(DependentWidget), isNot(paints..rect(color: color0)));
|
||||
|
||||
// Changing accessibility contrast works.
|
||||
await tester.pumpWidget(
|
||||
MediaQuery(
|
||||
data: const MediaQueryData(highContrast: true),
|
||||
child: DependentWidget(color: contrastDependentColor1),
|
||||
),
|
||||
);
|
||||
|
||||
expect(tester.takeException(), null);
|
||||
expect(find.byType(DependentWidget), paints..rect(color: color0));
|
||||
expect(find.byType(DependentWidget), isNot(paints..rect(color: color1)));
|
||||
|
||||
// Asserts when the required dependency is missing.
|
||||
await tester.pumpWidget(DependentWidget(color: contrastDependentColor1));
|
||||
expect(tester.takeException()?.toString(), contains('does not contain a MediaQuery'));
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'Dynamic colors that are only dependent on elevation level should not claim unnecessary dependencies, '
|
||||
'and its resolved color should change when its dependency changes',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.base,
|
||||
child: DependentWidget(color: elevationDependentColor1),
|
||||
),
|
||||
);
|
||||
|
||||
expect(tester.takeException(), null);
|
||||
expect(find.byType(DependentWidget), paints..rect(color: color1));
|
||||
expect(find.byType(DependentWidget), isNot(paints..rect(color: color0)));
|
||||
|
||||
// Changing UI elevation works.
|
||||
await tester.pumpWidget(
|
||||
CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.elevated,
|
||||
child: DependentWidget(color: elevationDependentColor1),
|
||||
),
|
||||
);
|
||||
|
||||
expect(tester.takeException(), null);
|
||||
expect(find.byType(DependentWidget), paints..rect(color: color0));
|
||||
expect(find.byType(DependentWidget), isNot(paints..rect(color: color1)));
|
||||
|
||||
// Asserts when the required dependency is missing.
|
||||
await tester.pumpWidget(DependentWidget(color: elevationDependentColor1));
|
||||
expect(tester.takeException()?.toString(), contains('does not contain a CupertinoUserInterfaceLevel'));
|
||||
});
|
||||
|
||||
testWidgets('Dynamic color with all 3 depedencies works', (WidgetTester tester) async {
|
||||
final Color dynamicRainbowColor1 = CupertinoDynamicColor(
|
||||
color: color0,
|
||||
darkColor: color1,
|
||||
highContrastColor: color2,
|
||||
darkHighContrastColor: color3,
|
||||
darkElevatedColor: color4,
|
||||
highContrastElevatedColor: color5,
|
||||
darkHighContrastElevatedColor: color6,
|
||||
elevatedColor: color7,
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.light, highContrast: false),
|
||||
child: CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.base,
|
||||
child: DependentWidget(color: dynamicRainbowColor1),
|
||||
),
|
||||
),
|
||||
);
|
||||
expect(find.byType(DependentWidget), paints..rect(color: color0));
|
||||
|
||||
await tester.pumpWidget(
|
||||
MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.dark, highContrast: false),
|
||||
child: CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.base,
|
||||
child: DependentWidget(color: dynamicRainbowColor1),
|
||||
),
|
||||
),
|
||||
);
|
||||
expect(find.byType(DependentWidget), paints..rect(color: color1));
|
||||
|
||||
await tester.pumpWidget(
|
||||
MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.light, highContrast: true),
|
||||
child: CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.base,
|
||||
child: DependentWidget(color: dynamicRainbowColor1),
|
||||
),
|
||||
),
|
||||
);
|
||||
expect(find.byType(DependentWidget), paints..rect(color: color2));
|
||||
|
||||
await tester.pumpWidget(
|
||||
MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.dark, highContrast: true),
|
||||
child: CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.base,
|
||||
child: DependentWidget(color: dynamicRainbowColor1),
|
||||
),
|
||||
),
|
||||
);
|
||||
expect(find.byType(DependentWidget), paints..rect(color: color3));
|
||||
|
||||
await tester.pumpWidget(
|
||||
MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.dark, highContrast: false),
|
||||
child: CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.elevated,
|
||||
child: DependentWidget(color: dynamicRainbowColor1),
|
||||
),
|
||||
),
|
||||
);
|
||||
expect(find.byType(DependentWidget), paints..rect(color: color4));
|
||||
|
||||
await tester.pumpWidget(
|
||||
MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.light, highContrast: true),
|
||||
child: CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.elevated,
|
||||
child: DependentWidget(color: dynamicRainbowColor1),
|
||||
),
|
||||
),
|
||||
);
|
||||
expect(find.byType(DependentWidget), paints..rect(color: color5));
|
||||
|
||||
await tester.pumpWidget(
|
||||
MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.dark, highContrast: true),
|
||||
child: CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.elevated,
|
||||
child: DependentWidget(color: dynamicRainbowColor1),
|
||||
),
|
||||
),
|
||||
);
|
||||
expect(find.byType(DependentWidget), paints..rect(color: color6));
|
||||
|
||||
await tester.pumpWidget(
|
||||
MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.light, highContrast: false),
|
||||
child: CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.elevated,
|
||||
child: DependentWidget(color: dynamicRainbowColor1),
|
||||
),
|
||||
),
|
||||
);
|
||||
expect(find.byType(DependentWidget), paints..rect(color: color7));
|
||||
});
|
||||
|
||||
group('CupertinoSystemColors widget', () {
|
||||
CupertinoSystemColorsData colors;
|
||||
setUp(() { colors = null; });
|
||||
|
||||
Widget systemColorGetter(BuildContext context) {
|
||||
colors = CupertinoSystemColors.of(context);
|
||||
return const Placeholder();
|
||||
}
|
||||
|
||||
testWidgets('exists in CupertinoApp', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(CupertinoApp(home: Builder(builder: systemColorGetter)));
|
||||
expect(colors.systemBackground, CupertinoSystemColors.fallbackValues.systemBackground);
|
||||
});
|
||||
|
||||
testWidgets('resolves against its own BuildContext', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
theme: const CupertinoThemeData(brightness: Brightness.dark),
|
||||
home: CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.elevated,
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return CupertinoSystemColors(
|
||||
child: Builder(builder: systemColorGetter),
|
||||
data: CupertinoSystemColors.of(context).resolveColors(context),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// In widget tests the OS colors should fallback to `fallbackValues`.
|
||||
expect(colors.systemBackground, isNot(CupertinoSystemColors.fallbackValues.systemBackground));
|
||||
expect(colors.systemBackground.value, CupertinoSystemColors.fallbackValues.systemBackground.darkElevatedColor.value);
|
||||
|
||||
colors = null;
|
||||
// Changing dependencies works.
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
theme: const CupertinoThemeData(brightness: Brightness.light),
|
||||
home: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.elevated,
|
||||
child: CupertinoSystemColors(
|
||||
child: Builder(builder: systemColorGetter),
|
||||
data: CupertinoSystemColors.of(context).resolveColors(context),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(colors.systemBackground.value, CupertinoSystemColors.fallbackValues.systemBackground.elevatedColor.value);
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('CupertinoDynamicColor used in a CupertinoTheme', (WidgetTester tester) async {
|
||||
CupertinoDynamicColor color;
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
theme: CupertinoThemeData(
|
||||
brightness: Brightness.dark,
|
||||
primaryColor: dynamicColor,
|
||||
),
|
||||
home: Builder(
|
||||
builder: (BuildContext context) {
|
||||
color = CupertinoTheme.of(context).primaryColor;
|
||||
return const Placeholder();
|
||||
}
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(color.value, dynamicColor.darkColor.value);
|
||||
|
||||
// Changing dependencies works.
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
theme: CupertinoThemeData(
|
||||
brightness: Brightness.light,
|
||||
primaryColor: dynamicColor,
|
||||
),
|
||||
home: Builder(
|
||||
builder: (BuildContext context) {
|
||||
color = CupertinoTheme.of(context).primaryColor;
|
||||
return const Placeholder();
|
||||
}
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(color.value, dynamicColor.color.value);
|
||||
|
||||
// Having a dependency below the CupertinoTheme widget works.
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
theme: CupertinoThemeData(primaryColor: dynamicColor),
|
||||
home: MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.light, highContrast: false),
|
||||
child: CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.base,
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
color = CupertinoTheme.of(context).primaryColor;
|
||||
return const Placeholder();
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(color.value, dynamicColor.color.value);
|
||||
|
||||
// Changing dependencies works.
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
// No brightness is explicitly specified here so it should defer to MediaQuery.
|
||||
theme: CupertinoThemeData(primaryColor: dynamicColor),
|
||||
home: MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.dark, highContrast: true),
|
||||
child: CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.elevated,
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
color = CupertinoTheme.of(context).primaryColor;
|
||||
return const Placeholder();
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(color.value, dynamicColor.darkHighContrastElevatedColor.value);
|
||||
});
|
||||
|
||||
group('MaterialApp:', () {
|
||||
Color color;
|
||||
setUp(() { color = null; });
|
||||
|
||||
testWidgets('dynamic color works in cupertino override theme', (WidgetTester tester) async {
|
||||
final CupertinoDynamicColor Function() typedColor = () => color;
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(
|
||||
cupertinoOverrideTheme: CupertinoThemeData(
|
||||
brightness: Brightness.dark,
|
||||
primaryColor: dynamicColor,
|
||||
),
|
||||
),
|
||||
home: MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.light, highContrast: false),
|
||||
child: CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.base,
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
color = CupertinoTheme.of(context).primaryColor;
|
||||
return const Placeholder();
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Explicit brightness is respected.
|
||||
expect(typedColor().value, dynamicColor.darkColor.value);
|
||||
color = null;
|
||||
|
||||
// Changing dependencies works.
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(
|
||||
cupertinoOverrideTheme: CupertinoThemeData(
|
||||
brightness: Brightness.dark,
|
||||
primaryColor: dynamicColor,
|
||||
),
|
||||
),
|
||||
home: MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.dark, highContrast: true),
|
||||
child: CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.elevated,
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
color = CupertinoTheme.of(context).primaryColor;
|
||||
return const Placeholder();
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(typedColor().value, dynamicColor.darkHighContrastElevatedColor.value);
|
||||
});
|
||||
|
||||
testWidgets('dynamic color does not work in a material theme', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
// This will create a MaterialBasedCupertinoThemeData with primaryColor set to `dynamicColor`.
|
||||
theme: ThemeData(colorScheme: ColorScheme.dark(primary: dynamicColor)),
|
||||
home: MediaQuery(
|
||||
data: const MediaQueryData(platformBrightness: Brightness.dark, highContrast: true),
|
||||
child: CupertinoUserInterfaceLevel(
|
||||
data: CupertinoUserInterfaceLevelData.elevated,
|
||||
child: Builder(
|
||||
builder: (BuildContext context) {
|
||||
color = CupertinoTheme.of(context).primaryColor;
|
||||
return const Placeholder();
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// The color is not resolved.
|
||||
expect(color, dynamicColor);
|
||||
expect(color, isNot(dynamicColor.darkHighContrastElevatedColor));
|
||||
});
|
||||
});
|
||||
|
||||
group('CupertinoSystemColors', () {
|
||||
final Color dynamicColor0 = CupertinoDynamicColor.withBrightness(
|
||||
color: const Color(0x00000000),
|
||||
darkColor: const Color(0x00000000)
|
||||
);
|
||||
final Color dynamicColor1 = CupertinoDynamicColor.withBrightness(
|
||||
color: const Color(0x00000001),
|
||||
darkColor: const Color(0x00000000)
|
||||
);
|
||||
|
||||
final CupertinoSystemColorsData system0 = CupertinoSystemColorsData(
|
||||
label: dynamicColor0,
|
||||
secondaryLabel: dynamicColor0,
|
||||
tertiaryLabel: dynamicColor0,
|
||||
quaternaryLabel: dynamicColor0,
|
||||
systemFill: dynamicColor0,
|
||||
secondarySystemFill: dynamicColor0,
|
||||
tertiarySystemFill: dynamicColor0,
|
||||
quaternarySystemFill: dynamicColor0,
|
||||
placeholderText: dynamicColor0,
|
||||
systemBackground: dynamicColor0,
|
||||
secondarySystemBackground: dynamicColor0,
|
||||
tertiarySystemBackground: dynamicColor0,
|
||||
systemGroupedBackground: dynamicColor0,
|
||||
secondarySystemGroupedBackground: dynamicColor0,
|
||||
tertiarySystemGroupedBackground: dynamicColor0,
|
||||
separator: dynamicColor0,
|
||||
opaqueSeparator: dynamicColor0,
|
||||
link: dynamicColor0,
|
||||
systemBlue: dynamicColor0,
|
||||
systemGreen: dynamicColor0,
|
||||
systemIndigo: dynamicColor0,
|
||||
systemOrange: dynamicColor0,
|
||||
systemPink: dynamicColor0,
|
||||
systemPurple: dynamicColor0,
|
||||
systemRed: dynamicColor0,
|
||||
systemTeal: dynamicColor0,
|
||||
systemYellow: dynamicColor0,
|
||||
systemGray: dynamicColor0,
|
||||
systemGray2: dynamicColor0,
|
||||
systemGray3: dynamicColor0,
|
||||
systemGray4: dynamicColor0,
|
||||
systemGray5: dynamicColor0,
|
||||
systemGray6: dynamicColor0,
|
||||
);
|
||||
|
||||
test('CupertinoSystemColorsData.== and CupertinoSystemColorsData.copyWith', () {
|
||||
expect(system0, system0);
|
||||
expect(system0, system0.copyWith());
|
||||
expect(system0, system0.copyWith(link: dynamicColor0));
|
||||
final CupertinoSystemColorsData withDifferentLink = system0.copyWith(link: dynamicColor1);
|
||||
expect(withDifferentLink.link, dynamicColor1);
|
||||
expect(system0, isNot(withDifferentLink));
|
||||
});
|
||||
|
||||
test('CupertinoSystemColorsData.hashCode', () {
|
||||
expect(system0.hashCode, system0.hashCode);
|
||||
expect(system0.hashCode, system0.copyWith().hashCode);
|
||||
expect(system0.hashCode, system0.copyWith(link: dynamicColor0).hashCode);
|
||||
expect(system0.hashCode, isNot(system0.copyWith(link: dynamicColor1).hashCode));
|
||||
});
|
||||
|
||||
test('CupertinoSystemColorsData.debugFillProperties', () {
|
||||
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
||||
system0.debugFillProperties(builder);
|
||||
|
||||
expect(
|
||||
builder.properties
|
||||
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
|
||||
.map((DiagnosticsNode node) => node.toString())
|
||||
.toList(),
|
||||
<String>[
|
||||
'label: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'secondaryLabel: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'tertiaryLabel: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'quaternaryLabel: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemFill: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'secondarySystemFill: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'tertiarySystemFill: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'quaternarySystemFill: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'placeholderText: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemBackground: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'secondarySystemBackground: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'tertiarySystemBackground: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemGroupedBackground: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'secondarySystemGroupedBackground: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'tertiarySystemGroupedBackground: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'separator: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'opaqueSeparator: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'link: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemBlue: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemGreen: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemIndigo: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemOrange: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemPink: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemPurple: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemRed: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemTeal: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemYellow: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemGray: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemGray2: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemGray3: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemGray4: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemGray5: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
'systemGray6: CupertinoDynamicColor(*color = Color(0x00000000)*)',
|
||||
],
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
@ -24,26 +24,28 @@ void main() {
|
||||
final Key sliderKey = UniqueKey();
|
||||
double value = 0.0;
|
||||
|
||||
await tester.pumpWidget(Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Material(
|
||||
child: Center(
|
||||
child: CupertinoSlider(
|
||||
key: sliderKey,
|
||||
value: value,
|
||||
onChanged: (double newValue) {
|
||||
setState(() {
|
||||
value = newValue;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
home: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Material(
|
||||
child: Center(
|
||||
child: CupertinoSlider(
|
||||
key: sliderKey,
|
||||
value: value,
|
||||
onChanged: (double newValue) {
|
||||
setState(() { value = newValue; });
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
);
|
||||
|
||||
expect(value, equals(0.0));
|
||||
await tester.tap(find.byKey(sliderKey));
|
||||
@ -58,26 +60,28 @@ void main() {
|
||||
final Key sliderKey = UniqueKey();
|
||||
double value = 0.0;
|
||||
|
||||
await tester.pumpWidget(Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Material(
|
||||
child: Center(
|
||||
child: CupertinoSlider(
|
||||
key: sliderKey,
|
||||
value: value,
|
||||
onChanged: (double newValue) {
|
||||
setState(() {
|
||||
value = newValue;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
home: Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Material(
|
||||
child: Center(
|
||||
child: CupertinoSlider(
|
||||
key: sliderKey,
|
||||
value: value,
|
||||
onChanged: (double newValue) {
|
||||
setState(() { value = newValue; });
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
);
|
||||
|
||||
expect(value, equals(0.0));
|
||||
await tester.tap(find.byKey(sliderKey));
|
||||
@ -93,29 +97,31 @@ void main() {
|
||||
double value = 0.0;
|
||||
int numberOfTimesOnChangeStartIsCalled = 0;
|
||||
|
||||
await tester.pumpWidget(Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Material(
|
||||
child: Center(
|
||||
child: CupertinoSlider(
|
||||
key: sliderKey,
|
||||
value: value,
|
||||
onChanged: (double newValue) {
|
||||
setState(() {
|
||||
value = newValue;
|
||||
});
|
||||
},
|
||||
onChangeStart: (double value) {
|
||||
numberOfTimesOnChangeStartIsCalled++;
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
home: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Material(
|
||||
child: Center(
|
||||
child: CupertinoSlider(
|
||||
key: sliderKey,
|
||||
value: value,
|
||||
onChanged: (double newValue) {
|
||||
setState(() { value = newValue; });
|
||||
},
|
||||
onChangeStart: (double value) {
|
||||
numberOfTimesOnChangeStartIsCalled++;
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
);
|
||||
|
||||
await _dragSlider(tester, sliderKey);
|
||||
|
||||
@ -132,29 +138,31 @@ void main() {
|
||||
double value = 0.0;
|
||||
int numberOfTimesOnChangeEndIsCalled = 0;
|
||||
|
||||
await tester.pumpWidget(Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Material(
|
||||
child: Center(
|
||||
child: CupertinoSlider(
|
||||
key: sliderKey,
|
||||
value: value,
|
||||
onChanged: (double newValue) {
|
||||
setState(() {
|
||||
value = newValue;
|
||||
});
|
||||
},
|
||||
onChangeEnd: (double value) {
|
||||
numberOfTimesOnChangeEndIsCalled++;
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
home: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Material(
|
||||
child: Center(
|
||||
child: CupertinoSlider(
|
||||
key: sliderKey,
|
||||
value: value,
|
||||
onChanged: (double newValue) {
|
||||
setState(() { value = newValue; });
|
||||
},
|
||||
onChangeEnd: (double value) {
|
||||
numberOfTimesOnChangeEndIsCalled++;
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
);
|
||||
|
||||
await _dragSlider(tester, sliderKey);
|
||||
|
||||
@ -172,32 +180,34 @@ void main() {
|
||||
double startValue;
|
||||
double endValue;
|
||||
|
||||
await tester.pumpWidget(Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Material(
|
||||
child: Center(
|
||||
child: CupertinoSlider(
|
||||
key: sliderKey,
|
||||
value: value,
|
||||
onChanged: (double newValue) {
|
||||
setState(() {
|
||||
value = newValue;
|
||||
});
|
||||
},
|
||||
onChangeStart: (double value) {
|
||||
startValue = value;
|
||||
},
|
||||
onChangeEnd: (double value) {
|
||||
endValue = value;
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
home: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Material(
|
||||
child: Center(
|
||||
child: CupertinoSlider(
|
||||
key: sliderKey,
|
||||
value: value,
|
||||
onChanged: (double newValue) {
|
||||
setState(() { value = newValue; });
|
||||
},
|
||||
onChangeStart: (double value) {
|
||||
startValue = value;
|
||||
},
|
||||
onChangeEnd: (double value) {
|
||||
endValue = value;
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
);
|
||||
|
||||
expect(value, equals(0.0));
|
||||
|
||||
@ -224,36 +234,34 @@ void main() {
|
||||
double startValue;
|
||||
double endValue;
|
||||
|
||||
await tester.pumpWidget(Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Material(
|
||||
child: Center(
|
||||
child: CupertinoSlider(
|
||||
key: sliderKey,
|
||||
value: value,
|
||||
onChanged: (double newValue) {
|
||||
setState(() {
|
||||
value = newValue;
|
||||
});
|
||||
},
|
||||
onChangeStart: (double value) {
|
||||
setState(() {
|
||||
startValue = value;
|
||||
});
|
||||
},
|
||||
onChangeEnd: (double value) {
|
||||
setState(() {
|
||||
endValue = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
home: Directionality(
|
||||
textDirection: TextDirection.rtl,
|
||||
child: StatefulBuilder(
|
||||
builder: (BuildContext context, StateSetter setState) {
|
||||
return Material(
|
||||
child: Center(
|
||||
child: CupertinoSlider(
|
||||
key: sliderKey,
|
||||
value: value,
|
||||
onChanged: (double newValue) {
|
||||
setState(() { value = newValue; });
|
||||
},
|
||||
onChangeStart: (double value) {
|
||||
setState(() { startValue = value; });
|
||||
},
|
||||
onChangeEnd: (double value) {
|
||||
setState(() { endValue = value; });
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
);
|
||||
|
||||
expect(value, equals(0.0));
|
||||
|
||||
@ -277,13 +285,18 @@ void main() {
|
||||
testWidgets('Slider Semantics', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
|
||||
await tester.pumpWidget(Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: CupertinoSlider(
|
||||
value: 0.5,
|
||||
onChanged: (double v) { },
|
||||
await tester.pumpWidget(
|
||||
MediaQuery(
|
||||
data: const MediaQueryData(),
|
||||
child: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: CupertinoSlider(
|
||||
value: 0.5,
|
||||
onChanged: (double v) { },
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
);
|
||||
|
||||
expect(semantics, hasSemantics(
|
||||
TestSemantics.root(
|
||||
@ -296,20 +309,25 @@ void main() {
|
||||
textDirection: TextDirection.ltr,
|
||||
actions: SemanticsAction.decrease.index | SemanticsAction.increase.index,
|
||||
),
|
||||
]
|
||||
],
|
||||
),
|
||||
ignoreRect: true,
|
||||
ignoreTransform: true,
|
||||
));
|
||||
|
||||
// Disable slider
|
||||
await tester.pumpWidget(const Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: CupertinoSlider(
|
||||
value: 0.5,
|
||||
onChanged: null,
|
||||
await tester.pumpWidget(
|
||||
const MediaQuery(
|
||||
data: MediaQueryData(),
|
||||
child: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: CupertinoSlider(
|
||||
value: 0.5,
|
||||
onChanged: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
);
|
||||
|
||||
expect(semantics, hasSemantics(
|
||||
TestSemantics.root(),
|
||||
@ -323,13 +341,17 @@ void main() {
|
||||
testWidgets('Slider Semantics can be updated', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
double value = 0.5;
|
||||
await tester.pumpWidget(Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: CupertinoSlider(
|
||||
value: value,
|
||||
onChanged: (double v) { },
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
home: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: CupertinoSlider(
|
||||
value: value,
|
||||
onChanged: (double v) { },
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
);
|
||||
|
||||
expect(tester.getSemantics(find.byType(CupertinoSlider)), matchesSemantics(
|
||||
hasIncreaseAction: true,
|
||||
@ -341,13 +363,17 @@ void main() {
|
||||
));
|
||||
|
||||
value = 0.6;
|
||||
await tester.pumpWidget(Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: CupertinoSlider(
|
||||
value: value,
|
||||
onChanged: (double v) { },
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
home: Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: CupertinoSlider(
|
||||
value: value,
|
||||
onChanged: (double v) { },
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
);
|
||||
|
||||
expect(tester.getSemantics(find.byType(CupertinoSlider)), matchesSemantics(
|
||||
hasIncreaseAction: true,
|
||||
@ -413,4 +439,108 @@ void main() {
|
||||
paints..rrect(color: CupertinoColors.activeGreen),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Themes can be overridden by dynamic colors', (WidgetTester tester) async {
|
||||
final CupertinoDynamicColor activeColor = CupertinoDynamicColor(
|
||||
color: const Color(0x00000001),
|
||||
darkColor: const Color(0x00000002),
|
||||
elevatedColor: const Color(0x00000003),
|
||||
highContrastColor: const Color(0x00000004),
|
||||
darkElevatedColor: const Color(0x00000005),
|
||||
darkHighContrastColor: const Color(0x00000006),
|
||||
highContrastElevatedColor: const Color(0x00000007),
|
||||
darkHighContrastElevatedColor: const Color(0x00000008),
|
||||
);
|
||||
|
||||
Widget withTraits(Brightness brightness, CupertinoUserInterfaceLevelData level, bool highContrast) {
|
||||
return CupertinoTheme(
|
||||
data: CupertinoThemeData(brightness: brightness),
|
||||
child: CupertinoUserInterfaceLevel(
|
||||
data: level,
|
||||
child: MediaQuery(
|
||||
data: MediaQueryData(highContrast: highContrast),
|
||||
child: Center(
|
||||
child: CupertinoSlider(
|
||||
activeColor: activeColor,
|
||||
onChanged: (double value) { },
|
||||
value: 0.5,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(CupertinoApp(home: withTraits(Brightness.light, CupertinoUserInterfaceLevelData.base, false)));
|
||||
expect(find.byType(CupertinoSlider), paints..rrect(color: activeColor.color));
|
||||
|
||||
await tester.pumpWidget(CupertinoApp(home: withTraits(Brightness.dark, CupertinoUserInterfaceLevelData.base, false)));
|
||||
expect(find.byType(CupertinoSlider), paints..rrect(color: activeColor.darkColor));
|
||||
|
||||
await tester.pumpWidget(CupertinoApp(home: withTraits(Brightness.dark, CupertinoUserInterfaceLevelData.elevated, false)));
|
||||
expect(find.byType(CupertinoSlider), paints..rrect(color: activeColor.darkElevatedColor));
|
||||
|
||||
await tester.pumpWidget(CupertinoApp(home: withTraits(Brightness.dark, CupertinoUserInterfaceLevelData.base, true)));
|
||||
expect(find.byType(CupertinoSlider), paints..rrect(color: activeColor.darkHighContrastColor));
|
||||
|
||||
await tester.pumpWidget(CupertinoApp(home: withTraits(Brightness.dark, CupertinoUserInterfaceLevelData.elevated, true)));
|
||||
expect(find.byType(CupertinoSlider), paints..rrect(color: activeColor.darkHighContrastElevatedColor));
|
||||
|
||||
await tester.pumpWidget(CupertinoApp(home: withTraits(Brightness.light, CupertinoUserInterfaceLevelData.base, true)));
|
||||
expect(find.byType(CupertinoSlider), paints..rrect(color: activeColor.highContrastColor));
|
||||
|
||||
await tester.pumpWidget(CupertinoApp(home: withTraits(Brightness.light, CupertinoUserInterfaceLevelData.elevated, false)));
|
||||
expect(find.byType(CupertinoSlider), paints..rrect(color: activeColor.elevatedColor));
|
||||
|
||||
await tester.pumpWidget(CupertinoApp(home: withTraits(Brightness.light, CupertinoUserInterfaceLevelData.elevated, true)));
|
||||
expect(find.byType(CupertinoSlider), paints..rrect(color: activeColor.highContrastElevatedColor));
|
||||
});
|
||||
|
||||
testWidgets('track color is dynamic', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
theme: const CupertinoThemeData(brightness: Brightness.light),
|
||||
home: Center(
|
||||
child: CupertinoSlider(
|
||||
activeColor: CupertinoColors.activeGreen,
|
||||
onChanged: (double value) { },
|
||||
value: 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
find.byType(CupertinoSlider),
|
||||
paints..rrect(color: CupertinoSystemColors.fallbackValues.systemFill.color),
|
||||
);
|
||||
|
||||
expect(
|
||||
find.byType(CupertinoSlider),
|
||||
isNot(paints..rrect(color: CupertinoSystemColors.fallbackValues.systemFill.darkColor)),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
theme: const CupertinoThemeData(brightness: Brightness.dark),
|
||||
home: Center(
|
||||
child: CupertinoSlider(
|
||||
activeColor: CupertinoColors.activeGreen,
|
||||
onChanged: (double value) { },
|
||||
value: 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
find.byType(CupertinoSlider),
|
||||
paints..rrect(color: CupertinoSystemColors.fallbackValues.systemFill.darkColor),
|
||||
);
|
||||
|
||||
expect(
|
||||
find.byType(CupertinoSlider),
|
||||
isNot(paints..rrect(color: CupertinoSystemColors.fallbackValues.systemFill.color)),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user