[Material] Bottom app bar theme (#24156)
* [WIP] BAB theme * [WIP] BAB theme * Update goldens * Extract helper function in tests * Update Goldens version * Add tests * [WIP] Hans first round comments * Added test * Added docs * Hans second round comments * Fixed analyzer error * Hans third round comments * ambient * Change [BottomAppBarTheme.of] to static * Final doc change
This commit is contained in:
parent
77512a3c46
commit
090c3bcd0e
@ -21,6 +21,7 @@ export 'src/material/app_bar.dart';
|
|||||||
export 'src/material/arc.dart';
|
export 'src/material/arc.dart';
|
||||||
export 'src/material/back_button.dart';
|
export 'src/material/back_button.dart';
|
||||||
export 'src/material/bottom_app_bar.dart';
|
export 'src/material/bottom_app_bar.dart';
|
||||||
|
export 'src/material/bottom_app_bar_theme.dart';
|
||||||
export 'src/material/bottom_navigation_bar.dart';
|
export 'src/material/bottom_navigation_bar.dart';
|
||||||
export 'src/material/bottom_sheet.dart';
|
export 'src/material/bottom_sheet.dart';
|
||||||
export 'src/material/button.dart';
|
export 'src/material/button.dart';
|
||||||
|
@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
import 'bottom_app_bar_theme.dart';
|
||||||
import 'material.dart';
|
import 'material.dart';
|
||||||
import 'scaffold.dart';
|
import 'scaffold.dart';
|
||||||
import 'theme.dart';
|
import 'theme.dart';
|
||||||
@ -41,19 +42,23 @@ import 'theme.dart';
|
|||||||
class BottomAppBar extends StatefulWidget {
|
class BottomAppBar extends StatefulWidget {
|
||||||
/// Creates a bottom application bar.
|
/// Creates a bottom application bar.
|
||||||
///
|
///
|
||||||
/// The [color], [elevation], and [clipBehavior] arguments must not be null.
|
/// The [clipBehavior] argument must not be null.
|
||||||
/// Additionally, [elevation] must be non-negative.
|
/// Additionally, [elevation] must be non-negative.
|
||||||
|
///
|
||||||
|
/// If [color], [elevation], or [shape] are null, their [BottomAppBarTheme] values will be used.
|
||||||
|
/// If the corresponding [BottomAppBarTheme] property is null, then the default
|
||||||
|
/// specified in the property's documentation will be used.
|
||||||
const BottomAppBar({
|
const BottomAppBar({
|
||||||
Key key,
|
Key key,
|
||||||
this.color,
|
this.color,
|
||||||
this.elevation = 8.0,
|
this.elevation,
|
||||||
this.shape,
|
this.shape,
|
||||||
this.clipBehavior = Clip.none,
|
this.clipBehavior = Clip.none,
|
||||||
this.notchMargin = 4.0,
|
this.notchMargin = 4.0,
|
||||||
this.child,
|
this.child,
|
||||||
}) : assert(elevation != null),
|
}) : assert(clipBehavior != null),
|
||||||
assert(elevation >= 0.0),
|
assert(elevation == null || elevation >= 0.0),
|
||||||
assert(clipBehavior != null),
|
assert(notchMargin != null),
|
||||||
super(key: key);
|
super(key: key);
|
||||||
|
|
||||||
/// The widget below this widget in the tree.
|
/// The widget below this widget in the tree.
|
||||||
@ -66,7 +71,8 @@ class BottomAppBar extends StatefulWidget {
|
|||||||
|
|
||||||
/// The bottom app bar's background color.
|
/// The bottom app bar's background color.
|
||||||
///
|
///
|
||||||
/// When null defaults to [ThemeData.bottomAppBarColor].
|
/// If this property is null then [ThemeData.bottomAppBarTheme.color] is used,
|
||||||
|
/// if that's null then [ThemeData.bottomAppBarColor] is used.
|
||||||
final Color color;
|
final Color color;
|
||||||
|
|
||||||
/// The z-coordinate at which to place this bottom app bar relative to its
|
/// The z-coordinate at which to place this bottom app bar relative to its
|
||||||
@ -75,12 +81,14 @@ class BottomAppBar extends StatefulWidget {
|
|||||||
/// This controls the size of the shadow below the bottom app bar. The
|
/// This controls the size of the shadow below the bottom app bar. The
|
||||||
/// value is non-negative.
|
/// value is non-negative.
|
||||||
///
|
///
|
||||||
/// Defaults to 8, the appropriate elevation for bottom app bars.
|
/// If this property is null then [ThemeData.bottomAppBarTheme.elevation] is used,
|
||||||
|
/// if that's null, the default value is 8.
|
||||||
final double elevation;
|
final double elevation;
|
||||||
|
|
||||||
/// The notch that is made for the floating action button.
|
/// The notch that is made for the floating action button.
|
||||||
///
|
///
|
||||||
/// If null the bottom app bar will be rectangular with no notch.
|
/// If this property is null then [ThemeData.bottomAppBarTheme.shape] is used,
|
||||||
|
/// if that's null then the shape will be rectangular with no notch.
|
||||||
final NotchedShape shape;
|
final NotchedShape shape;
|
||||||
|
|
||||||
/// {@macro flutter.widgets.Clip}
|
/// {@macro flutter.widgets.Clip}
|
||||||
@ -98,6 +106,7 @@ class BottomAppBar extends StatefulWidget {
|
|||||||
|
|
||||||
class _BottomAppBarState extends State<BottomAppBar> {
|
class _BottomAppBarState extends State<BottomAppBar> {
|
||||||
ValueListenable<ScaffoldGeometry> geometryListenable;
|
ValueListenable<ScaffoldGeometry> geometryListenable;
|
||||||
|
static const double _defaultElevation = 8.0;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didChangeDependencies() {
|
void didChangeDependencies() {
|
||||||
@ -107,17 +116,20 @@ class _BottomAppBarState extends State<BottomAppBar> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final CustomClipper<Path> clipper = widget.shape != null
|
final ThemeData theme = Theme.of(context);
|
||||||
|
final BottomAppBarTheme babTheme = BottomAppBarTheme.of(context);
|
||||||
|
final NotchedShape notchedShape = widget.shape ?? babTheme.shape;
|
||||||
|
final CustomClipper<Path> clipper = notchedShape != null
|
||||||
? _BottomAppBarClipper(
|
? _BottomAppBarClipper(
|
||||||
geometry: geometryListenable,
|
geometry: geometryListenable,
|
||||||
shape: widget.shape,
|
shape: notchedShape,
|
||||||
notchMargin: widget.notchMargin,
|
notchMargin: widget.notchMargin,
|
||||||
)
|
)
|
||||||
: const ShapeBorderClipper(shape: RoundedRectangleBorder());
|
: const ShapeBorderClipper(shape: RoundedRectangleBorder());
|
||||||
return PhysicalShape(
|
return PhysicalShape(
|
||||||
clipper: clipper,
|
clipper: clipper,
|
||||||
elevation: widget.elevation,
|
elevation: widget.elevation ?? babTheme.elevation ?? _defaultElevation,
|
||||||
color: widget.color ?? Theme.of(context).bottomAppBarColor,
|
color: widget.color ?? babTheme.color ?? theme.bottomAppBarColor,
|
||||||
clipBehavior: widget.clipBehavior,
|
clipBehavior: widget.clipBehavior,
|
||||||
child: Material(
|
child: Material(
|
||||||
type: MaterialType.transparency,
|
type: MaterialType.transparency,
|
||||||
|
108
packages/flutter/lib/src/material/bottom_app_bar_theme.dart
Normal file
108
packages/flutter/lib/src/material/bottom_app_bar_theme.dart
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
// Copyright 2018 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 'dart:ui' show lerpDouble;
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
import 'theme.dart';
|
||||||
|
|
||||||
|
/// Defines default property values for descendant [BottomAppBar] widgets.
|
||||||
|
///
|
||||||
|
/// Descendant widgets obtain the current [BottomAppBarTheme] object using
|
||||||
|
/// `BottomAppBarTheme.of(context)`. Instances of [BottomAppBarTheme] can be
|
||||||
|
/// customized with [BottomAppBarTheme.copyWith].
|
||||||
|
///
|
||||||
|
/// Typically a [BottomAppBarTheme] is specified as part of the overall [Theme]
|
||||||
|
/// with [ThemeData.bottomAppBarTheme].
|
||||||
|
///
|
||||||
|
/// All [BottomAppBarTheme] properties are `null` by default. When null, the
|
||||||
|
/// [BottomAppBar] constructor provides defaults.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [ThemeData], which describes the overall theme information for the
|
||||||
|
/// application.
|
||||||
|
class BottomAppBarTheme extends Diagnosticable {
|
||||||
|
/// Creates a theme that can be used for [ThemeData.BottomAppBarTheme].
|
||||||
|
const BottomAppBarTheme({
|
||||||
|
this.color,
|
||||||
|
this.elevation,
|
||||||
|
this.shape,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Default value for [BottomAppBar.color].
|
||||||
|
///
|
||||||
|
/// If null, [BottomAppBar] uses [ThemeData.bottomAppBarColor].
|
||||||
|
final Color color;
|
||||||
|
|
||||||
|
/// Default value for [BottomAppBar.elevation].
|
||||||
|
final double elevation;
|
||||||
|
|
||||||
|
/// Default value for [BottomAppBar.shape].
|
||||||
|
final NotchedShape shape;
|
||||||
|
|
||||||
|
/// Creates a copy of this object but with the given fields replaced with the
|
||||||
|
/// new values.
|
||||||
|
BottomAppBarTheme copyWith({
|
||||||
|
Color color,
|
||||||
|
double elevation,
|
||||||
|
NotchedShape shape,
|
||||||
|
}) {
|
||||||
|
return BottomAppBarTheme(
|
||||||
|
color: color ?? this.color,
|
||||||
|
elevation: elevation ?? this.elevation,
|
||||||
|
shape: shape ?? this.shape,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The [ThemeData.bottomAppBarTheme] property of the ambient [Theme].
|
||||||
|
static BottomAppBarTheme of(BuildContext context) {
|
||||||
|
return Theme.of(context).bottomAppBarTheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Linearly interpolate between two BAB themes.
|
||||||
|
///
|
||||||
|
/// The argument `t` must not be null.
|
||||||
|
///
|
||||||
|
/// {@macro dart.ui.shadow.lerp}
|
||||||
|
static BottomAppBarTheme lerp(BottomAppBarTheme a, BottomAppBarTheme b, double t) {
|
||||||
|
assert(t != null);
|
||||||
|
return BottomAppBarTheme(
|
||||||
|
color: Color.lerp(a?.color, b?.color, t),
|
||||||
|
elevation: lerpDouble(a?.elevation, b?.elevation, t),
|
||||||
|
shape: t < 0.5 ? a?.shape : b?.shape,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return hashValues(
|
||||||
|
color,
|
||||||
|
elevation,
|
||||||
|
shape,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
if (identical(this, other))
|
||||||
|
return true;
|
||||||
|
if (other.runtimeType != runtimeType)
|
||||||
|
return false;
|
||||||
|
final BottomAppBarTheme typedOther = other;
|
||||||
|
return typedOther.color == color
|
||||||
|
&& typedOther.elevation == elevation
|
||||||
|
&& typedOther.shape == shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
|
super.debugFillProperties(properties);
|
||||||
|
properties.add(DiagnosticsProperty<Color>('color', color, defaultValue: null));
|
||||||
|
properties.add(DiagnosticsProperty<double>('elevation', elevation, defaultValue: null));
|
||||||
|
properties.add(DiagnosticsProperty<NotchedShape>('shape', shape, defaultValue: null));
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
import 'bottom_app_bar_theme.dart';
|
||||||
import 'button_theme.dart';
|
import 'button_theme.dart';
|
||||||
import 'chip_theme.dart';
|
import 'chip_theme.dart';
|
||||||
import 'color_scheme.dart';
|
import 'color_scheme.dart';
|
||||||
@ -151,6 +152,7 @@ class ThemeData extends Diagnosticable {
|
|||||||
TargetPlatform platform,
|
TargetPlatform platform,
|
||||||
MaterialTapTargetSize materialTapTargetSize,
|
MaterialTapTargetSize materialTapTargetSize,
|
||||||
PageTransitionsTheme pageTransitionsTheme,
|
PageTransitionsTheme pageTransitionsTheme,
|
||||||
|
BottomAppBarTheme bottomAppBarTheme,
|
||||||
ColorScheme colorScheme,
|
ColorScheme colorScheme,
|
||||||
DialogTheme dialogTheme,
|
DialogTheme dialogTheme,
|
||||||
Typography typography,
|
Typography typography,
|
||||||
@ -242,6 +244,7 @@ class ThemeData extends Diagnosticable {
|
|||||||
valueIndicatorTextStyle: accentTextTheme.body2,
|
valueIndicatorTextStyle: accentTextTheme.body2,
|
||||||
);
|
);
|
||||||
tabBarTheme ??= const TabBarTheme();
|
tabBarTheme ??= const TabBarTheme();
|
||||||
|
bottomAppBarTheme ??= const BottomAppBarTheme();
|
||||||
chipTheme ??= ChipThemeData.fromDefaults(
|
chipTheme ??= ChipThemeData.fromDefaults(
|
||||||
secondaryColor: primaryColor,
|
secondaryColor: primaryColor,
|
||||||
brightness: brightness,
|
brightness: brightness,
|
||||||
@ -294,6 +297,7 @@ class ThemeData extends Diagnosticable {
|
|||||||
platform: platform,
|
platform: platform,
|
||||||
materialTapTargetSize: materialTapTargetSize,
|
materialTapTargetSize: materialTapTargetSize,
|
||||||
pageTransitionsTheme: pageTransitionsTheme,
|
pageTransitionsTheme: pageTransitionsTheme,
|
||||||
|
bottomAppBarTheme: bottomAppBarTheme,
|
||||||
colorScheme: colorScheme,
|
colorScheme: colorScheme,
|
||||||
dialogTheme: dialogTheme,
|
dialogTheme: dialogTheme,
|
||||||
typography: typography,
|
typography: typography,
|
||||||
@ -355,6 +359,7 @@ class ThemeData extends Diagnosticable {
|
|||||||
@required this.platform,
|
@required this.platform,
|
||||||
@required this.materialTapTargetSize,
|
@required this.materialTapTargetSize,
|
||||||
@required this.pageTransitionsTheme,
|
@required this.pageTransitionsTheme,
|
||||||
|
@required this.bottomAppBarTheme,
|
||||||
@required this.colorScheme,
|
@required this.colorScheme,
|
||||||
@required this.dialogTheme,
|
@required this.dialogTheme,
|
||||||
@required this.typography,
|
@required this.typography,
|
||||||
@ -401,6 +406,7 @@ class ThemeData extends Diagnosticable {
|
|||||||
assert(platform != null),
|
assert(platform != null),
|
||||||
assert(materialTapTargetSize != null),
|
assert(materialTapTargetSize != null),
|
||||||
assert(pageTransitionsTheme != null),
|
assert(pageTransitionsTheme != null),
|
||||||
|
assert(bottomAppBarTheme != null),
|
||||||
assert(colorScheme != null),
|
assert(colorScheme != null),
|
||||||
assert(dialogTheme != null),
|
assert(dialogTheme != null),
|
||||||
assert(typography != null);
|
assert(typography != null);
|
||||||
@ -619,6 +625,9 @@ class ThemeData extends Diagnosticable {
|
|||||||
/// builder is not found, a builder whose platform is null is used.
|
/// builder is not found, a builder whose platform is null is used.
|
||||||
final PageTransitionsTheme pageTransitionsTheme;
|
final PageTransitionsTheme pageTransitionsTheme;
|
||||||
|
|
||||||
|
/// A theme for customizing the shape, elevation, and color of a [BottomAppBar].
|
||||||
|
final BottomAppBarTheme bottomAppBarTheme;
|
||||||
|
|
||||||
/// A set of thirteen colors that can be used to configure the
|
/// A set of thirteen colors that can be used to configure the
|
||||||
/// color properties of most components.
|
/// color properties of most components.
|
||||||
///
|
///
|
||||||
@ -693,6 +702,7 @@ class ThemeData extends Diagnosticable {
|
|||||||
TargetPlatform platform,
|
TargetPlatform platform,
|
||||||
MaterialTapTargetSize materialTapTargetSize,
|
MaterialTapTargetSize materialTapTargetSize,
|
||||||
PageTransitionsTheme pageTransitionsTheme,
|
PageTransitionsTheme pageTransitionsTheme,
|
||||||
|
BottomAppBarTheme bottomAppBarTheme,
|
||||||
ColorScheme colorScheme,
|
ColorScheme colorScheme,
|
||||||
DialogTheme dialogTheme,
|
DialogTheme dialogTheme,
|
||||||
Typography typography,
|
Typography typography,
|
||||||
@ -743,6 +753,7 @@ class ThemeData extends Diagnosticable {
|
|||||||
platform: platform ?? this.platform,
|
platform: platform ?? this.platform,
|
||||||
materialTapTargetSize: materialTapTargetSize ?? this.materialTapTargetSize,
|
materialTapTargetSize: materialTapTargetSize ?? this.materialTapTargetSize,
|
||||||
pageTransitionsTheme: pageTransitionsTheme ?? this.pageTransitionsTheme,
|
pageTransitionsTheme: pageTransitionsTheme ?? this.pageTransitionsTheme,
|
||||||
|
bottomAppBarTheme: bottomAppBarTheme ?? this.bottomAppBarTheme,
|
||||||
colorScheme: colorScheme ?? this.colorScheme,
|
colorScheme: colorScheme ?? this.colorScheme,
|
||||||
dialogTheme: dialogTheme ?? this.dialogTheme,
|
dialogTheme: dialogTheme ?? this.dialogTheme,
|
||||||
typography: typography ?? this.typography,
|
typography: typography ?? this.typography,
|
||||||
@ -871,6 +882,7 @@ class ThemeData extends Diagnosticable {
|
|||||||
platform: t < 0.5 ? a.platform : b.platform,
|
platform: t < 0.5 ? a.platform : b.platform,
|
||||||
materialTapTargetSize: t < 0.5 ? a.materialTapTargetSize : b.materialTapTargetSize,
|
materialTapTargetSize: t < 0.5 ? a.materialTapTargetSize : b.materialTapTargetSize,
|
||||||
pageTransitionsTheme: t < 0.5 ? a.pageTransitionsTheme : b.pageTransitionsTheme,
|
pageTransitionsTheme: t < 0.5 ? a.pageTransitionsTheme : b.pageTransitionsTheme,
|
||||||
|
bottomAppBarTheme: BottomAppBarTheme.lerp(a.bottomAppBarTheme, b.bottomAppBarTheme, t),
|
||||||
colorScheme: ColorScheme.lerp(a.colorScheme, b.colorScheme, t),
|
colorScheme: ColorScheme.lerp(a.colorScheme, b.colorScheme, t),
|
||||||
dialogTheme: DialogTheme.lerp(a.dialogTheme, b.dialogTheme, t),
|
dialogTheme: DialogTheme.lerp(a.dialogTheme, b.dialogTheme, t),
|
||||||
typography: Typography.lerp(a.typography, b.typography, t),
|
typography: Typography.lerp(a.typography, b.typography, t),
|
||||||
@ -929,6 +941,7 @@ class ThemeData extends Diagnosticable {
|
|||||||
(otherData.platform == platform) &&
|
(otherData.platform == platform) &&
|
||||||
(otherData.materialTapTargetSize == materialTapTargetSize) &&
|
(otherData.materialTapTargetSize == materialTapTargetSize) &&
|
||||||
(otherData.pageTransitionsTheme == pageTransitionsTheme) &&
|
(otherData.pageTransitionsTheme == pageTransitionsTheme) &&
|
||||||
|
(otherData.bottomAppBarTheme == bottomAppBarTheme) &&
|
||||||
(otherData.colorScheme == colorScheme) &&
|
(otherData.colorScheme == colorScheme) &&
|
||||||
(otherData.dialogTheme == dialogTheme) &&
|
(otherData.dialogTheme == dialogTheme) &&
|
||||||
(otherData.typography == typography) &&
|
(otherData.typography == typography) &&
|
||||||
@ -987,6 +1000,7 @@ class ThemeData extends Diagnosticable {
|
|||||||
platform,
|
platform,
|
||||||
materialTapTargetSize,
|
materialTapTargetSize,
|
||||||
pageTransitionsTheme,
|
pageTransitionsTheme,
|
||||||
|
bottomAppBarTheme,
|
||||||
colorScheme,
|
colorScheme,
|
||||||
dialogTheme,
|
dialogTheme,
|
||||||
typography,
|
typography,
|
||||||
@ -1040,6 +1054,7 @@ class ThemeData extends Diagnosticable {
|
|||||||
properties.add(DiagnosticsProperty<ChipThemeData>('chipTheme', chipTheme));
|
properties.add(DiagnosticsProperty<ChipThemeData>('chipTheme', chipTheme));
|
||||||
properties.add(DiagnosticsProperty<MaterialTapTargetSize>('materialTapTargetSize', materialTapTargetSize));
|
properties.add(DiagnosticsProperty<MaterialTapTargetSize>('materialTapTargetSize', materialTapTargetSize));
|
||||||
properties.add(DiagnosticsProperty<PageTransitionsTheme>('pageTransitionsTheme', pageTransitionsTheme));
|
properties.add(DiagnosticsProperty<PageTransitionsTheme>('pageTransitionsTheme', pageTransitionsTheme));
|
||||||
|
properties.add(DiagnosticsProperty<BottomAppBarTheme>('bottomAppBarTheme', bottomAppBarTheme, defaultValue: defaultData.bottomAppBarTheme));
|
||||||
properties.add(DiagnosticsProperty<ColorScheme>('colorScheme', colorScheme, defaultValue: defaultData.colorScheme));
|
properties.add(DiagnosticsProperty<ColorScheme>('colorScheme', colorScheme, defaultValue: defaultData.colorScheme));
|
||||||
properties.add(DiagnosticsProperty<DialogTheme>('dialogTheme', dialogTheme, defaultValue: defaultData.dialogTheme));
|
properties.add(DiagnosticsProperty<DialogTheme>('dialogTheme', dialogTheme, defaultValue: defaultData.dialogTheme));
|
||||||
properties.add(DiagnosticsProperty<Typography>('typography', typography, defaultValue: defaultData.typography));
|
properties.add(DiagnosticsProperty<Typography>('typography', typography, defaultValue: defaultData.typography));
|
||||||
|
133
packages/flutter/test/material/bottom_app_bar_theme_test.dart
Normal file
133
packages/flutter/test/material/bottom_app_bar_theme_test.dart
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
// Copyright 2018 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 'dart:io' show Platform;
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
testWidgets('BAB theme overrides color', (WidgetTester tester) async {
|
||||||
|
const Color themedColor = Colors.black87;
|
||||||
|
const BottomAppBarTheme theme = BottomAppBarTheme(color: themedColor);
|
||||||
|
|
||||||
|
await tester.pumpWidget(_withTheme(theme));
|
||||||
|
|
||||||
|
final PhysicalShape widget = _getBabRenderObject(tester);
|
||||||
|
expect(widget.color, themedColor);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('BAB color - Widget', (WidgetTester tester) async {
|
||||||
|
const Color themeColor = Colors.white10;
|
||||||
|
const Color babThemeColor = Colors.black87;
|
||||||
|
const Color babColor = Colors.pink;
|
||||||
|
const BottomAppBarTheme theme = BottomAppBarTheme(color: babThemeColor);
|
||||||
|
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
theme: ThemeData(bottomAppBarTheme: theme, bottomAppBarColor: themeColor),
|
||||||
|
home: const Scaffold(body: BottomAppBar(color: babColor)),
|
||||||
|
));
|
||||||
|
|
||||||
|
final PhysicalShape widget = _getBabRenderObject(tester);
|
||||||
|
expect(widget.color, babColor);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('BAB color - BabTheme', (WidgetTester tester) async {
|
||||||
|
const Color themeColor = Colors.white10;
|
||||||
|
const Color babThemeColor = Colors.black87;
|
||||||
|
const BottomAppBarTheme theme = BottomAppBarTheme(color: babThemeColor);
|
||||||
|
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
theme: ThemeData(bottomAppBarTheme: theme, bottomAppBarColor: themeColor),
|
||||||
|
home: const Scaffold(body: BottomAppBar()),
|
||||||
|
));
|
||||||
|
|
||||||
|
final PhysicalShape widget = _getBabRenderObject(tester);
|
||||||
|
expect(widget.color, babThemeColor);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('BAB color - Theme', (WidgetTester tester) async {
|
||||||
|
const Color themeColor = Colors.white10;
|
||||||
|
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
theme: ThemeData(bottomAppBarColor: themeColor),
|
||||||
|
home: const Scaffold(body: BottomAppBar()),
|
||||||
|
));
|
||||||
|
|
||||||
|
final PhysicalShape widget = _getBabRenderObject(tester);
|
||||||
|
expect(widget.color, themeColor);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('BAB color - Default', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
theme: ThemeData(),
|
||||||
|
home: const Scaffold(body: BottomAppBar()),
|
||||||
|
));
|
||||||
|
|
||||||
|
final PhysicalShape widget = _getBabRenderObject(tester);
|
||||||
|
|
||||||
|
expect(widget.color, Colors.white);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('BAB theme customizes shape', (WidgetTester tester) async {
|
||||||
|
const BottomAppBarTheme theme = BottomAppBarTheme(
|
||||||
|
color: Colors.white30,
|
||||||
|
shape: CircularNotchedRectangle(),
|
||||||
|
elevation: 1.0,
|
||||||
|
);
|
||||||
|
|
||||||
|
await tester.pumpWidget(_withTheme(theme));
|
||||||
|
|
||||||
|
await expectLater(
|
||||||
|
find.byKey(_painterKey),
|
||||||
|
matchesGoldenFile('bottom_app_bar_theme.custom_shape.png'),
|
||||||
|
skip: !Platform.isLinux,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('BAB theme does not affect defaults', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(const MaterialApp(
|
||||||
|
home: Scaffold(body: BottomAppBar()),
|
||||||
|
));
|
||||||
|
|
||||||
|
final PhysicalShape widget = _getBabRenderObject(tester);
|
||||||
|
|
||||||
|
expect(widget.color, Colors.white);
|
||||||
|
expect(widget.elevation, equals(8.0));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
PhysicalShape _getBabRenderObject(WidgetTester tester) {
|
||||||
|
return tester.widget<PhysicalShape>(
|
||||||
|
find.descendant(
|
||||||
|
of: find.byType(BottomAppBar),
|
||||||
|
matching: find.byType(PhysicalShape),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Key _painterKey = UniqueKey();
|
||||||
|
|
||||||
|
Widget _withTheme(BottomAppBarTheme theme) {
|
||||||
|
return MaterialApp(
|
||||||
|
theme: ThemeData(bottomAppBarTheme: theme),
|
||||||
|
home: Scaffold(
|
||||||
|
floatingActionButton: const FloatingActionButton(onPressed: null),
|
||||||
|
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
|
||||||
|
bottomNavigationBar: RepaintBoundary(
|
||||||
|
key: _painterKey,
|
||||||
|
child: BottomAppBar(
|
||||||
|
child: Row(
|
||||||
|
children: const <Widget>[
|
||||||
|
Icon(Icons.add),
|
||||||
|
Expanded(child: SizedBox()),
|
||||||
|
Icon(Icons.add),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user