Unverified Commit f3049c77 authored by MH Johnson's avatar MH Johnson Committed by GitHub

add navigation bar component (#83047)

parent 61bce1d8
......@@ -99,6 +99,8 @@ export 'src/material/material_localizations.dart';
export 'src/material/material_state.dart';
export 'src/material/material_state_mixin.dart';
export 'src/material/mergeable_material.dart';
export 'src/material/navigation_bar.dart';
export 'src/material/navigation_bar_theme.dart';
export 'src/material/navigation_rail.dart';
export 'src/material/navigation_rail_theme.dart';
export 'src/material/no_splash.dart';
......
This diff is collapsed.
// Copyright 2014 The Flutter 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 'dart:ui' show lerpDouble;
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'material_state.dart';
import 'navigation_bar.dart';
import 'theme.dart';
/// Defines default property values for descendant [NavigationBar]
/// widgets.
///
/// Descendant widgets obtain the current [NavigationBarThemeData] object
/// using `NavigationBarTheme.of(context)`. Instances of
/// [NavigationBarThemeData] can be customized with
/// [NavigationBarThemeData.copyWith].
///
/// Typically a [NavigationBarThemeData] is specified as part of the
/// overall [Theme] with [ThemeData.navigationBarTheme]. Alternatively, a
/// [NavigationBarTheme] inherited widget can be used to theme [NavigationBar]s
/// in a subtree of widgets.
///
/// All [NavigationBarThemeData] properties are `null` by default.
/// When null, the [NavigationBar] will provide its own defaults based on the
/// overall [Theme]'s textTheme and colorScheme. See the individual
/// [NavigationBar] properties for details.
///
/// See also:
///
/// * [ThemeData], which describes the overall theme information for the
/// application.
@immutable
class NavigationBarThemeData with Diagnosticable {
/// Creates a theme that can be used for [ThemeData.navigationBarTheme] and
/// [NavigationBarTheme].
const NavigationBarThemeData({
this.height,
this.backgroundColor,
this.indicatorColor,
this.labelTextStyle,
this.iconTheme,
this.labelBehavior,
});
/// Overrides the default value of [NavigationBar.height].
final double? height;
/// Overrides the default value of [NavigationBar.backgroundColor].
final Color? backgroundColor;
/// Overrides the default value of [NavigationBar]'s selection indicator.
final Color? indicatorColor;
/// The style to merge with the default text style for
/// [NavigationDestination] labels.
///
/// You can use this to specify a different style when the label is selected.
final MaterialStateProperty<TextStyle?>? labelTextStyle;
/// The theme to merge with the default icon theme for
/// [NavigationDestination] icons.
///
/// You can use this to specify a different icon theme when the icon is
/// selected.
final MaterialStateProperty<IconThemeData?>? iconTheme;
/// Overrides the default value of [NavigationBar.labelBehavior].
final NavigationDestinationLabelBehavior? labelBehavior;
/// Creates a copy of this object with the given fields replaced with the
/// new values.
NavigationBarThemeData copyWith({
double? height,
Color? backgroundColor,
Color? indicatorColor,
MaterialStateProperty<TextStyle?>? labelTextStyle,
MaterialStateProperty<IconThemeData?>? iconTheme,
NavigationDestinationLabelBehavior? labelBehavior,
}) {
return NavigationBarThemeData(
height: height ?? this.height,
backgroundColor: backgroundColor ?? this.backgroundColor,
indicatorColor: indicatorColor ?? this.indicatorColor,
labelTextStyle: labelTextStyle ?? this.labelTextStyle,
iconTheme: iconTheme ?? this.iconTheme,
labelBehavior: labelBehavior ?? this.labelBehavior,
);
}
/// Linearly interpolate between two navigation rail themes.
///
/// If both arguments are null then null is returned.
///
/// {@macro dart.ui.shadow.lerp}
static NavigationBarThemeData? lerp(NavigationBarThemeData? a, NavigationBarThemeData? b, double t) {
assert(t != null);
if (a == null && b == null)
return null;
return NavigationBarThemeData(
height: lerpDouble(a?.height, b?.height, t),
backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t),
indicatorColor: Color.lerp(a?.indicatorColor, b?.indicatorColor, t),
labelTextStyle: _lerpProperties<TextStyle?>(a?.labelTextStyle, b?.labelTextStyle, t, TextStyle.lerp),
iconTheme: _lerpProperties<IconThemeData?>(a?.iconTheme, b?.iconTheme, t, IconThemeData.lerp),
labelBehavior: t < 0.5 ? a?.labelBehavior : b?.labelBehavior,
);
}
@override
int get hashCode {
return hashValues(
height,
backgroundColor,
indicatorColor,
labelTextStyle,
iconTheme,
labelBehavior,
);
}
@override
bool operator ==(Object other) {
if (identical(this, other))
return true;
if (other.runtimeType != runtimeType)
return false;
return other is NavigationBarThemeData
&& other.height == height
&& other.backgroundColor == backgroundColor
&& other.indicatorColor == indicatorColor
&& other.labelTextStyle == labelTextStyle
&& other.iconTheme == iconTheme
&& other.labelBehavior == labelBehavior;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DoubleProperty('height', height, defaultValue: null));
properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null));
properties.add(ColorProperty('indicatorColor', indicatorColor, defaultValue: null));
properties.add(DiagnosticsProperty<MaterialStateProperty<TextStyle?>>('labelTextStyle', labelTextStyle, defaultValue: null));
properties.add(DiagnosticsProperty<MaterialStateProperty<IconThemeData?>>('iconTheme', iconTheme, defaultValue: null));
properties.add(DiagnosticsProperty<NavigationDestinationLabelBehavior>('labelBehavior', labelBehavior, defaultValue: null));
}
static MaterialStateProperty<T>? _lerpProperties<T>(
MaterialStateProperty<T>? a,
MaterialStateProperty<T>? b,
double t,
T Function(T?, T?, double) lerpFunction,
) {
// Avoid creating a _LerpProperties object for a common case.
if (a == null && b == null)
return null;
return _LerpProperties<T>(a, b, t, lerpFunction);
}
}
class _LerpProperties<T> implements MaterialStateProperty<T> {
const _LerpProperties(this.a, this.b, this.t, this.lerpFunction);
final MaterialStateProperty<T>? a;
final MaterialStateProperty<T>? b;
final double t;
final T Function(T?, T?, double) lerpFunction;
@override
T resolve(Set<MaterialState> states) {
final T? resolvedA = a?.resolve(states);
final T? resolvedB = b?.resolve(states);
return lerpFunction(resolvedA, resolvedB, t);
}
}
/// An inherited widget that defines visual properties for [NavigationBar]s and
/// [NavigationDestination]s in this widget's subtree.
///
/// Values specified here are used for [NavigationBar] properties that are not
/// given an explicit non-null value.
///
/// See also:
///
/// * [ThemeData.navigationBarTheme], which describes the
/// [NavigationBarThemeData] in the overall theme for the application.
class NavigationBarTheme extends InheritedTheme {
/// Creates a navigation rail theme that controls the
/// [NavigationBarThemeData] properties for a [NavigationBar].
///
/// The data argument must not be null.
const NavigationBarTheme({
Key? key,
required this.data,
required Widget child,
}) : assert(data != null), super(key: key, child: child);
/// Specifies the background color, label text style, icon theme, and label
/// type values for descendant [NavigationBar] widgets.
final NavigationBarThemeData data;
/// The closest instance of this class that encloses the given context.
///
/// If there is no enclosing [NavigationBarTheme] widget, then
/// [ThemeData.navigationBarTheme] is used.
///
/// Typical usage is as follows:
///
/// ```dart
/// NavigationBarTheme theme = NavigationBarTheme.of(context);
/// ```
static NavigationBarThemeData of(BuildContext context) {
final NavigationBarTheme? navigationBarTheme = context.dependOnInheritedWidgetOfExactType<NavigationBarTheme>();
return navigationBarTheme?.data ?? Theme.of(context).navigationBarTheme;
}
@override
Widget wrap(BuildContext context, Widget child) {
return NavigationBarTheme(data: data, child: child);
}
@override
bool updateShouldNotify(NavigationBarTheme oldWidget) => data != oldWidget.data;
}
......@@ -28,6 +28,7 @@ import 'floating_action_button_theme.dart';
import 'ink_splash.dart';
import 'ink_well.dart' show InteractiveInkFeatureFactory;
import 'input_decorator.dart';
import 'navigation_bar_theme.dart';
import 'navigation_rail_theme.dart';
import 'outlined_button_theme.dart';
import 'page_transitions_theme.dart';
......@@ -317,6 +318,7 @@ class ThemeData with Diagnosticable {
ColorScheme? colorScheme,
DialogTheme? dialogTheme,
FloatingActionButtonThemeData? floatingActionButtonTheme,
NavigationBarThemeData? navigationBarTheme,
NavigationRailThemeData? navigationRailTheme,
Typography? typography,
NoDefaultCupertinoThemeData? cupertinoOverrideTheme,
......@@ -462,6 +464,7 @@ class ThemeData with Diagnosticable {
);
dialogTheme ??= const DialogTheme();
floatingActionButtonTheme ??= const FloatingActionButtonThemeData();
navigationBarTheme ??= const NavigationBarThemeData();
navigationRailTheme ??= const NavigationRailThemeData();
cupertinoOverrideTheme = cupertinoOverrideTheme?.noDefault();
snackBarTheme ??= const SnackBarThemeData();
......@@ -543,6 +546,7 @@ class ThemeData with Diagnosticable {
colorScheme: colorScheme,
dialogTheme: dialogTheme,
floatingActionButtonTheme: floatingActionButtonTheme,
navigationBarTheme: navigationBarTheme,
navigationRailTheme: navigationRailTheme,
typography: typography,
cupertinoOverrideTheme: cupertinoOverrideTheme,
......@@ -677,6 +681,7 @@ class ThemeData with Diagnosticable {
required this.colorScheme,
required this.dialogTheme,
required this.floatingActionButtonTheme,
required this.navigationBarTheme,
required this.navigationRailTheme,
required this.typography,
required this.cupertinoOverrideTheme,
......@@ -763,6 +768,7 @@ class ThemeData with Diagnosticable {
assert(colorScheme != null),
assert(dialogTheme != null),
assert(floatingActionButtonTheme != null),
assert(navigationBarTheme != null),
assert(navigationRailTheme != null),
assert(typography != null),
assert(snackBarTheme != null),
......@@ -1269,6 +1275,10 @@ class ThemeData with Diagnosticable {
/// [FloatingActionButton].
final FloatingActionButtonThemeData floatingActionButtonTheme;
/// A theme for customizing the background color, text style, and icon themes
/// of a [NavigationBar].
final NavigationBarThemeData navigationBarTheme;
/// A theme for customizing the background color, elevation, text style, and
/// icon themes of a [NavigationRail].
final NavigationRailThemeData navigationRailTheme;
......@@ -1485,6 +1495,7 @@ class ThemeData with Diagnosticable {
ColorScheme? colorScheme,
DialogTheme? dialogTheme,
FloatingActionButtonThemeData? floatingActionButtonTheme,
NavigationBarThemeData? navigationBarTheme,
NavigationRailThemeData? navigationRailTheme,
Typography? typography,
NoDefaultCupertinoThemeData? cupertinoOverrideTheme,
......@@ -1576,6 +1587,7 @@ class ThemeData with Diagnosticable {
colorScheme: (colorScheme ?? this.colorScheme).copyWith(brightness: brightness),
dialogTheme: dialogTheme ?? this.dialogTheme,
floatingActionButtonTheme: floatingActionButtonTheme ?? this.floatingActionButtonTheme,
navigationBarTheme: navigationBarTheme ?? this.navigationBarTheme,
navigationRailTheme: navigationRailTheme ?? this.navigationRailTheme,
typography: typography ?? this.typography,
cupertinoOverrideTheme: cupertinoOverrideTheme ?? this.cupertinoOverrideTheme,
......@@ -1737,6 +1749,7 @@ class ThemeData with Diagnosticable {
colorScheme: ColorScheme.lerp(a.colorScheme, b.colorScheme, t),
dialogTheme: DialogTheme.lerp(a.dialogTheme, b.dialogTheme, t),
floatingActionButtonTheme: FloatingActionButtonThemeData.lerp(a.floatingActionButtonTheme, b.floatingActionButtonTheme, t)!,
navigationBarTheme: NavigationBarThemeData.lerp(a.navigationBarTheme, b.navigationBarTheme, t)!,
navigationRailTheme: NavigationRailThemeData.lerp(a.navigationRailTheme, b.navigationRailTheme, t)!,
typography: Typography.lerp(a.typography, b.typography, t),
cupertinoOverrideTheme: t < 0.5 ? a.cupertinoOverrideTheme : b.cupertinoOverrideTheme,
......@@ -1826,6 +1839,7 @@ class ThemeData with Diagnosticable {
&& other.colorScheme == colorScheme
&& other.dialogTheme == dialogTheme
&& other.floatingActionButtonTheme == floatingActionButtonTheme
&& other.navigationBarTheme == navigationBarTheme
&& other.navigationRailTheme == navigationRailTheme
&& other.typography == typography
&& other.cupertinoOverrideTheme == cupertinoOverrideTheme
......@@ -1914,6 +1928,7 @@ class ThemeData with Diagnosticable {
colorScheme,
dialogTheme,
floatingActionButtonTheme,
navigationBarTheme,
navigationRailTheme,
typography,
cupertinoOverrideTheme,
......@@ -1999,6 +2014,7 @@ class ThemeData with Diagnosticable {
properties.add(DiagnosticsProperty<ColorScheme>('colorScheme', colorScheme, defaultValue: defaultData.colorScheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<DialogTheme>('dialogTheme', dialogTheme, defaultValue: defaultData.dialogTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<FloatingActionButtonThemeData>('floatingActionButtonThemeData', floatingActionButtonTheme, defaultValue: defaultData.floatingActionButtonTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<NavigationBarThemeData>('navigationBarTheme', navigationBarTheme, defaultValue: defaultData.navigationBarTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<NavigationRailThemeData>('navigationRailThemeData', navigationRailTheme, defaultValue: defaultData.navigationRailTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<Typography>('typography', typography, defaultValue: defaultData.typography, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<NoDefaultCupertinoThemeData>('cupertinoOverrideTheme', cupertinoOverrideTheme, defaultValue: defaultData.cupertinoOverrideTheme, level: DiagnosticLevel.debug));
......
This diff is collapsed.
// Copyright 2014 The Flutter 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/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
test('copyWith, ==, hashCode basics', () {
expect(const NavigationBarThemeData(), const NavigationBarThemeData().copyWith());
expect(const NavigationBarThemeData().hashCode, const NavigationBarThemeData().copyWith().hashCode);
});
testWidgets('Default debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
const NavigationBarThemeData().debugFillProperties(builder);
final List<String> description = builder.properties
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
.map((DiagnosticsNode node) => node.toString())
.toList();
expect(description, <String>[]);
});
testWidgets('Custom debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
NavigationBarThemeData(
height: 200.0,
backgroundColor: const Color(0x00000099),
indicatorColor: const Color(0x00000098),
labelTextStyle: MaterialStateProperty.all(const TextStyle(fontSize: 7.0)),
iconTheme: MaterialStateProperty.all(const IconThemeData(color: Color(0x00000097))),
labelBehavior: NavigationDestinationLabelBehavior.alwaysHide,
).debugFillProperties(builder);
final List<String> description = builder.properties
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
.map((DiagnosticsNode node) => node.toString())
.toList();
expect(description[0], 'height: 200.0');
expect(description[1], 'backgroundColor: Color(0x00000099)');
expect(description[2], 'indicatorColor: Color(0x00000098)');
expect(description[3], 'labelTextStyle: MaterialStateProperty.all(TextStyle(inherit: true, size: 7.0))');
// Ignore instance address for IconThemeData.
expect(description[4].contains('iconTheme: MaterialStateProperty.all(IconThemeData'), isTrue);
expect(description[4].contains('(color: Color(0x00000097))'), isTrue);
expect(description[5], 'labelBehavior: NavigationDestinationLabelBehavior.alwaysHide');
});
testWidgets('NavigationBarThemeData values are used when no NavigationBar properties are specified', (WidgetTester tester) async {
const double height = 200.0;
const Color backgroundColor = Color(0x00000001);
const Color indicatorColor = Color(0x00000002);
const double selectedIconSize = 25.0;
const double unselectedIconSize = 23.0;
const Color selectedIconColor = Color(0x00000003);
const Color unselectedIconColor = Color(0x00000004);
const double selectedIconOpacity = 0.99;
const double unselectedIconOpacity = 0.98;
const double selectedLabelFontSize = 13.0;
const double unselectedLabelFontSize = 11.0;
const NavigationDestinationLabelBehavior labelBehavior = NavigationDestinationLabelBehavior.alwaysShow;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
bottomNavigationBar: NavigationBarTheme(
data: NavigationBarThemeData(
height: height,
backgroundColor: backgroundColor,
indicatorColor: indicatorColor,
iconTheme: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return const IconThemeData(
size: selectedIconSize,
color: selectedIconColor,
opacity: selectedIconOpacity,
);
}
return const IconThemeData(
size: unselectedIconSize,
color: unselectedIconColor,
opacity: unselectedIconOpacity,
);
}),
labelTextStyle: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return const TextStyle(fontSize: selectedLabelFontSize);
}
return const TextStyle(fontSize: unselectedLabelFontSize);
}),
labelBehavior: labelBehavior,
),
child: NavigationBar(
selectedIndex: 0,
destinations: _destinations(),
),
),
),
),
);
expect(_barHeight(tester), height);
expect(_barMaterial(tester).color, backgroundColor);
expect(_indicator(tester)?.color, indicatorColor);
expect(_selectedIconTheme(tester).size, selectedIconSize);
expect(_selectedIconTheme(tester).color, selectedIconColor);
expect(_selectedIconTheme(tester).opacity, selectedIconOpacity);
expect(_unselectedIconTheme(tester).size, unselectedIconSize);
expect(_unselectedIconTheme(tester).color, unselectedIconColor);
expect(_unselectedIconTheme(tester).opacity, unselectedIconOpacity);
expect(_selectedLabelStyle(tester).fontSize, selectedLabelFontSize);
expect(_unselectedLabelStyle(tester).fontSize, unselectedLabelFontSize);
expect(_labelBehavior(tester), labelBehavior);
});
testWidgets('NavigationBar values take priority over NavigationBarThemeData values when both properties are specified', (WidgetTester tester) async {
const double height = 200.0;
const Color backgroundColor = Color(0x00000001);
const NavigationDestinationLabelBehavior labelBehavior = NavigationDestinationLabelBehavior.alwaysShow;
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
bottomNavigationBar: NavigationBarTheme(
data: const NavigationBarThemeData(
height: 100.0,
backgroundColor: Color(0x00000099),
labelBehavior: NavigationDestinationLabelBehavior.alwaysHide,
),
child: NavigationBar(
height: height,
backgroundColor: backgroundColor,
labelBehavior: labelBehavior,
selectedIndex: 0,
destinations: _destinations(),
),
),
),
),
);
expect(_barHeight(tester), height);
expect(_barMaterial(tester).color, backgroundColor);
expect(_labelBehavior(tester), labelBehavior);
});
}
List<NavigationDestination> _destinations() {
return const <NavigationDestination>[
NavigationDestination(
icon: Icon(Icons.favorite_border),
selectedIcon: Icon(Icons.favorite),
label: 'Abc',
),
NavigationDestination(
icon: Icon(Icons.star_border),
selectedIcon: Icon(Icons.star),
label: 'Def',
),
];
}
double _barHeight(WidgetTester tester) {
return tester.getRect(
find.byType(NavigationBar),
).height;
}
Material _barMaterial(WidgetTester tester) {
return tester.firstWidget<Material>(
find.descendant(
of: find.byType(NavigationBar),
matching: find.byType(Material),
),
);
}
BoxDecoration? _indicator(WidgetTester tester) {
return tester.firstWidget<Container>(
find.descendant(
of: find.byType(FadeTransition),
matching: find.byType(Container),
),
).decoration as BoxDecoration?;
}
IconThemeData _selectedIconTheme(WidgetTester tester) {
return _iconTheme(tester, Icons.favorite);
}
IconThemeData _unselectedIconTheme(WidgetTester tester) {
return _iconTheme(tester, Icons.star_border);
}
IconThemeData _iconTheme(WidgetTester tester, IconData icon) {
return tester.firstWidget<IconTheme>(
find.ancestor(
of: find.byIcon(icon),
matching: find.byType(IconTheme),
),
).data;
}
TextStyle _selectedLabelStyle(WidgetTester tester) {
return tester.widget<RichText>(
find.descendant(
of: find.text('Abc'),
matching: find.byType(RichText),
),
).text.style!;
}
TextStyle _unselectedLabelStyle(WidgetTester tester) {
return tester.widget<RichText>(
find.descendant(
of: find.text('Def'),
matching: find.byType(RichText),
),
).text.style!;
}
NavigationDestinationLabelBehavior _labelBehavior(WidgetTester tester) {
if (_opacityAboveLabel('Abc').evaluate().isNotEmpty && _opacityAboveLabel('Def').evaluate().isNotEmpty) {
return _labelOpacity(tester, 'Abc') == 1
? NavigationDestinationLabelBehavior.onlyShowSelected
: NavigationDestinationLabelBehavior.alwaysHide;
} else {
return NavigationDestinationLabelBehavior.alwaysShow;
}
}
Finder _opacityAboveLabel(String text) {
return find.ancestor(
of: find.text(text),
matching: find.byType(Opacity),
);
}
// Only valid when labelBehavior != alwaysShow.
double _labelOpacity(WidgetTester tester, String text) {
final Opacity opacityWidget = tester.widget<Opacity>(
find.ancestor(
of: find.text(text),
matching: find.byType(Opacity),
),
);
return opacityWidget.opacity;
}
......@@ -324,6 +324,7 @@ void main() {
colorScheme: const ColorScheme.light(),
dialogTheme: const DialogTheme(backgroundColor: Colors.black),
floatingActionButtonTheme: const FloatingActionButtonThemeData(backgroundColor: Colors.black),
navigationBarTheme: const NavigationBarThemeData(backgroundColor: Colors.black),
navigationRailTheme: const NavigationRailThemeData(backgroundColor: Colors.black),
typography: Typography.material2018(platform: TargetPlatform.android),
cupertinoOverrideTheme: null,
......@@ -420,6 +421,7 @@ void main() {
colorScheme: const ColorScheme.light(),
dialogTheme: const DialogTheme(backgroundColor: Colors.white),
floatingActionButtonTheme: const FloatingActionButtonThemeData(backgroundColor: Colors.white),
navigationBarTheme: const NavigationBarThemeData(backgroundColor: Colors.white),
navigationRailTheme: const NavigationRailThemeData(backgroundColor: Colors.white),
typography: Typography.material2018(platform: TargetPlatform.iOS),
cupertinoOverrideTheme: ThemeData.light().cupertinoOverrideTheme,
......@@ -497,6 +499,7 @@ void main() {
colorScheme: otherTheme.colorScheme,
dialogTheme: otherTheme.dialogTheme,
floatingActionButtonTheme: otherTheme.floatingActionButtonTheme,
navigationBarTheme: otherTheme.navigationBarTheme,
navigationRailTheme: otherTheme.navigationRailTheme,
typography: otherTheme.typography,
cupertinoOverrideTheme: otherTheme.cupertinoOverrideTheme,
......@@ -571,6 +574,7 @@ void main() {
expect(themeDataCopy.colorScheme, equals(otherTheme.colorScheme));
expect(themeDataCopy.dialogTheme, equals(otherTheme.dialogTheme));
expect(themeDataCopy.floatingActionButtonTheme, equals(otherTheme.floatingActionButtonTheme));
expect(themeDataCopy.navigationBarTheme, equals(otherTheme.navigationBarTheme));
expect(themeDataCopy.navigationRailTheme, equals(otherTheme.navigationRailTheme));
expect(themeDataCopy.typography, equals(otherTheme.typography));
expect(themeDataCopy.cupertinoOverrideTheme, equals(otherTheme.cupertinoOverrideTheme));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment