[Material] Theme-able elevation on dialogs. (#24169)
* Themable elevation on dialogs. * Added `BackgroundColor` in widget + theme * Addressing Comments * Fix test name * Add debugFillProperties test
This commit is contained in:
parent
e6d216cca8
commit
92efec3998
@ -41,16 +41,31 @@ class Dialog extends StatelessWidget {
|
|||||||
/// Typically used in conjunction with [showDialog].
|
/// Typically used in conjunction with [showDialog].
|
||||||
const Dialog({
|
const Dialog({
|
||||||
Key key,
|
Key key,
|
||||||
this.child,
|
this.backgroundColor,
|
||||||
|
this.elevation,
|
||||||
this.insetAnimationDuration = const Duration(milliseconds: 100),
|
this.insetAnimationDuration = const Duration(milliseconds: 100),
|
||||||
this.insetAnimationCurve = Curves.decelerate,
|
this.insetAnimationCurve = Curves.decelerate,
|
||||||
this.shape,
|
this.shape,
|
||||||
|
this.child,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
/// The widget below this widget in the tree.
|
/// {@template flutter.material.dialog.backgroundColor}
|
||||||
|
/// The background color of the surface of this [Dialog].
|
||||||
///
|
///
|
||||||
/// {@macro flutter.widgets.child}
|
/// This sets the [Material.color] on this [Dialog]'s [Material].
|
||||||
final Widget child;
|
///
|
||||||
|
/// If `null`, [ThemeData.cardColor] is used.
|
||||||
|
/// {@endtemplate}
|
||||||
|
final Color backgroundColor;
|
||||||
|
|
||||||
|
/// {@template flutter.material.dialog.elevation}
|
||||||
|
/// The z-coordinate of this [Dialog].
|
||||||
|
///
|
||||||
|
/// If null then [DialogTheme.elevation] is used, and if that's null then the
|
||||||
|
/// dialog's elevation is 24.0.
|
||||||
|
/// {@endtemplate}
|
||||||
|
/// {@macro flutter.material.material.elevation}
|
||||||
|
final double elevation;
|
||||||
|
|
||||||
/// The duration of the animation to show when the system keyboard intrudes
|
/// The duration of the animation to show when the system keyboard intrudes
|
||||||
/// into the space that the dialog is placed in.
|
/// into the space that the dialog is placed in.
|
||||||
@ -73,13 +88,15 @@ class Dialog extends StatelessWidget {
|
|||||||
/// {@endtemplate}
|
/// {@endtemplate}
|
||||||
final ShapeBorder shape;
|
final ShapeBorder shape;
|
||||||
|
|
||||||
Color _getColor(BuildContext context) {
|
/// The widget below this widget in the tree.
|
||||||
return Theme.of(context).dialogBackgroundColor;
|
///
|
||||||
}
|
/// {@macro flutter.widgets.child}
|
||||||
|
final Widget child;
|
||||||
|
|
||||||
// TODO(johnsonmh): Update default dialog border radius to 4.0 to match material spec.
|
// TODO(johnsonmh): Update default dialog border radius to 4.0 to match material spec.
|
||||||
static const RoundedRectangleBorder _defaultDialogShape =
|
static const RoundedRectangleBorder _defaultDialogShape =
|
||||||
RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0)));
|
RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0)));
|
||||||
|
static const double _defaultElevation = 24.0;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -98,11 +115,11 @@ class Dialog extends StatelessWidget {
|
|||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: const BoxConstraints(minWidth: 280.0),
|
constraints: const BoxConstraints(minWidth: 280.0),
|
||||||
child: Material(
|
child: Material(
|
||||||
elevation: 24.0,
|
color: backgroundColor ?? dialogTheme.backgroundColor ?? Theme.of(context).dialogBackgroundColor,
|
||||||
color: _getColor(context),
|
elevation: elevation ?? dialogTheme.elevation ?? _defaultElevation,
|
||||||
|
shape: shape ?? dialogTheme.shape ?? _defaultDialogShape,
|
||||||
type: MaterialType.card,
|
type: MaterialType.card,
|
||||||
child: child,
|
child: child,
|
||||||
shape: shape ?? dialogTheme.shape ?? _defaultDialogShape,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -190,6 +207,8 @@ class AlertDialog extends StatelessWidget {
|
|||||||
this.content,
|
this.content,
|
||||||
this.contentPadding = const EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 24.0),
|
this.contentPadding = const EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 24.0),
|
||||||
this.actions,
|
this.actions,
|
||||||
|
this.backgroundColor,
|
||||||
|
this.elevation,
|
||||||
this.semanticLabel,
|
this.semanticLabel,
|
||||||
this.shape,
|
this.shape,
|
||||||
}) : assert(contentPadding != null),
|
}) : assert(contentPadding != null),
|
||||||
@ -242,6 +261,13 @@ class AlertDialog extends StatelessWidget {
|
|||||||
/// from the [actions].
|
/// from the [actions].
|
||||||
final List<Widget> actions;
|
final List<Widget> actions;
|
||||||
|
|
||||||
|
/// {@macro flutter.material.dialog.backgroundColor}
|
||||||
|
final Color backgroundColor;
|
||||||
|
|
||||||
|
/// {@macro flutter.material.dialog.elevation}
|
||||||
|
/// {@macro flutter.material.material.elevation}
|
||||||
|
final double elevation;
|
||||||
|
|
||||||
/// The semantic label of the dialog used by accessibility frameworks to
|
/// The semantic label of the dialog used by accessibility frameworks to
|
||||||
/// announce screen transitions when the dialog is opened and closed.
|
/// announce screen transitions when the dialog is opened and closed.
|
||||||
///
|
///
|
||||||
@ -318,7 +344,12 @@ class AlertDialog extends StatelessWidget {
|
|||||||
child: dialogChild
|
child: dialogChild
|
||||||
);
|
);
|
||||||
|
|
||||||
return Dialog(child: dialogChild, shape: shape);
|
return Dialog(
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
elevation: elevation,
|
||||||
|
shape: shape,
|
||||||
|
child: dialogChild,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,6 +495,8 @@ class SimpleDialog extends StatelessWidget {
|
|||||||
this.titlePadding = const EdgeInsets.fromLTRB(24.0, 24.0, 24.0, 0.0),
|
this.titlePadding = const EdgeInsets.fromLTRB(24.0, 24.0, 24.0, 0.0),
|
||||||
this.children,
|
this.children,
|
||||||
this.contentPadding = const EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 16.0),
|
this.contentPadding = const EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 16.0),
|
||||||
|
this.backgroundColor,
|
||||||
|
this.elevation,
|
||||||
this.semanticLabel,
|
this.semanticLabel,
|
||||||
this.shape,
|
this.shape,
|
||||||
}) : assert(titlePadding != null),
|
}) : assert(titlePadding != null),
|
||||||
@ -507,6 +540,13 @@ class SimpleDialog extends StatelessWidget {
|
|||||||
/// the top padding ends up being 24 pixels.
|
/// the top padding ends up being 24 pixels.
|
||||||
final EdgeInsetsGeometry contentPadding;
|
final EdgeInsetsGeometry contentPadding;
|
||||||
|
|
||||||
|
/// {@macro flutter.material.dialog.backgroundColor}
|
||||||
|
final Color backgroundColor;
|
||||||
|
|
||||||
|
/// {@macro flutter.material.dialog.elevation}
|
||||||
|
/// {@macro flutter.material.material.elevation}
|
||||||
|
final double elevation;
|
||||||
|
|
||||||
/// The semantic label of the dialog used by accessibility frameworks to
|
/// The semantic label of the dialog used by accessibility frameworks to
|
||||||
/// announce screen transitions when the dialog is opened and closed.
|
/// announce screen transitions when the dialog is opened and closed.
|
||||||
///
|
///
|
||||||
@ -575,7 +615,12 @@ class SimpleDialog extends StatelessWidget {
|
|||||||
label: label,
|
label: label,
|
||||||
child: dialogChild,
|
child: dialogChild,
|
||||||
);
|
);
|
||||||
return Dialog(child: dialogChild, shape: shape);
|
return Dialog(
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
elevation: elevation,
|
||||||
|
shape: shape,
|
||||||
|
child: dialogChild,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:ui' show lerpDouble;
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
@ -23,15 +25,27 @@ import 'theme.dart';
|
|||||||
/// application.
|
/// application.
|
||||||
class DialogTheme extends Diagnosticable {
|
class DialogTheme extends Diagnosticable {
|
||||||
/// Creates a dialog theme that can be used for [ThemeData.dialogTheme].
|
/// Creates a dialog theme that can be used for [ThemeData.dialogTheme].
|
||||||
const DialogTheme({ this.shape });
|
const DialogTheme({ this.backgroundColor, this.elevation, this.shape });
|
||||||
|
|
||||||
|
/// Default value for [Dialog.backgroundColor].
|
||||||
|
final Color backgroundColor;
|
||||||
|
|
||||||
|
/// Default value for [Dialog.elevation].
|
||||||
|
///
|
||||||
|
/// If null, the [Dialog] elevation defaults to `24.0`.
|
||||||
|
final double elevation;
|
||||||
|
|
||||||
/// Default value for [Dialog.shape].
|
/// Default value for [Dialog.shape].
|
||||||
final ShapeBorder shape;
|
final ShapeBorder shape;
|
||||||
|
|
||||||
/// Creates a copy of this object but with the given fields replaced with the
|
/// Creates a copy of this object but with the given fields replaced with the
|
||||||
/// new values.
|
/// new values.
|
||||||
DialogTheme copyWith({ ShapeBorder shape }) {
|
DialogTheme copyWith({ Color backgroundColor, double elevation, ShapeBorder shape }) {
|
||||||
return DialogTheme(shape: shape ?? this.shape);
|
return DialogTheme(
|
||||||
|
backgroundColor: backgroundColor ?? this.backgroundColor,
|
||||||
|
elevation: elevation ?? this.elevation,
|
||||||
|
shape: shape ?? this.shape,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The data from the closest [DialogTheme] instance given the build context.
|
/// The data from the closest [DialogTheme] instance given the build context.
|
||||||
@ -47,7 +61,9 @@ class DialogTheme extends Diagnosticable {
|
|||||||
static DialogTheme lerp(DialogTheme a, DialogTheme b, double t) {
|
static DialogTheme lerp(DialogTheme a, DialogTheme b, double t) {
|
||||||
assert(t != null);
|
assert(t != null);
|
||||||
return DialogTheme(
|
return DialogTheme(
|
||||||
shape: ShapeBorder.lerp(a?.shape, b?.shape, t)
|
backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t),
|
||||||
|
elevation: lerpDouble(a?.elevation, b?.elevation, t),
|
||||||
|
shape: ShapeBorder.lerp(a?.shape, b?.shape, t),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,12 +77,16 @@ class DialogTheme extends Diagnosticable {
|
|||||||
if (other.runtimeType != runtimeType)
|
if (other.runtimeType != runtimeType)
|
||||||
return false;
|
return false;
|
||||||
final DialogTheme typedOther = other;
|
final DialogTheme typedOther = other;
|
||||||
return typedOther.shape == shape;
|
return typedOther.backgroundColor == backgroundColor
|
||||||
|
&& typedOther.elevation == elevation
|
||||||
|
&& typedOther.shape == shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
super.debugFillProperties(properties);
|
super.debugFillProperties(properties);
|
||||||
|
properties.add(DiagnosticsProperty<Color>('backgroundColor', backgroundColor));
|
||||||
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
|
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
|
||||||
|
properties.add(DiagnosticsProperty<double>('elevation', elevation));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,6 +194,7 @@ class Material extends StatefulWidget {
|
|||||||
/// the shape is rectangular, and the default color.
|
/// the shape is rectangular, and the default color.
|
||||||
final MaterialType type;
|
final MaterialType type;
|
||||||
|
|
||||||
|
/// {@template flutter.material.material.elevation}
|
||||||
/// The z-coordinate at which to place this material. This controls the size
|
/// The z-coordinate at which to place this material. This controls the size
|
||||||
/// of the shadow below the material.
|
/// of the shadow below the material.
|
||||||
///
|
///
|
||||||
@ -202,6 +203,7 @@ class Material extends StatefulWidget {
|
|||||||
///
|
///
|
||||||
/// Defaults to 0. Changing this value will cause the shadow to animate over
|
/// Defaults to 0. Changing this value will cause the shadow to animate over
|
||||||
/// [animationDuration].
|
/// [animationDuration].
|
||||||
|
/// {@endtemplate}
|
||||||
final double elevation;
|
final double elevation;
|
||||||
|
|
||||||
/// The color to paint the material.
|
/// The color to paint the material.
|
||||||
|
@ -35,6 +35,10 @@ MaterialApp _appWithAlertDialog(WidgetTester tester, AlertDialog dialog, {ThemeD
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Material _getMaterialFromDialog(WidgetTester tester) {
|
||||||
|
return tester.widget<Material>(find.descendant(of: find.byType(AlertDialog), matching: find.byType(Material)));
|
||||||
|
}
|
||||||
|
|
||||||
const ShapeBorder _defaultDialogShape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0)));
|
const ShapeBorder _defaultDialogShape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0)));
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@ -58,15 +62,29 @@ void main() {
|
|||||||
await tester.pumpWidget(_appWithAlertDialog(tester, dialog));
|
await tester.pumpWidget(_appWithAlertDialog(tester, dialog));
|
||||||
|
|
||||||
await tester.tap(find.text('X'));
|
await tester.tap(find.text('X'));
|
||||||
await tester.pump(); // start animation
|
await tester.pumpAndSettle();
|
||||||
await tester.pump(const Duration(seconds: 1));
|
|
||||||
|
|
||||||
expect(didPressOk, false);
|
expect(didPressOk, false);
|
||||||
await tester.tap(find.text('OK'));
|
await tester.tap(find.text('OK'));
|
||||||
expect(didPressOk, true);
|
expect(didPressOk, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Dialog background color', (WidgetTester tester) async {
|
testWidgets('Dialog background color from AlertDialog', (WidgetTester tester) async {
|
||||||
|
const Color customColor = Colors.pink;
|
||||||
|
const AlertDialog dialog = AlertDialog(
|
||||||
|
backgroundColor: customColor,
|
||||||
|
actions: <Widget>[ ],
|
||||||
|
);
|
||||||
|
await tester.pumpWidget(_appWithAlertDialog(tester, dialog, theme: ThemeData(brightness: Brightness.dark)));
|
||||||
|
|
||||||
|
await tester.tap(find.text('X'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
final Material materialWidget = _getMaterialFromDialog(tester);
|
||||||
|
expect(materialWidget.color, customColor);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Dialog Defaults', (WidgetTester tester) async {
|
||||||
const AlertDialog dialog = AlertDialog(
|
const AlertDialog dialog = AlertDialog(
|
||||||
title: Text('Title'),
|
title: Text('Title'),
|
||||||
content: Text('Y'),
|
content: Text('Y'),
|
||||||
@ -75,14 +93,27 @@ void main() {
|
|||||||
await tester.pumpWidget(_appWithAlertDialog(tester, dialog, theme: ThemeData(brightness: Brightness.dark)));
|
await tester.pumpWidget(_appWithAlertDialog(tester, dialog, theme: ThemeData(brightness: Brightness.dark)));
|
||||||
|
|
||||||
await tester.tap(find.text('X'));
|
await tester.tap(find.text('X'));
|
||||||
await tester.pump(); // start animation
|
await tester.pumpAndSettle();
|
||||||
await tester.pump(const Duration(seconds: 1));
|
|
||||||
|
|
||||||
final StatefulElement widget = tester.element(
|
final Material materialWidget = _getMaterialFromDialog(tester);
|
||||||
find.descendant(of: find.byType(AlertDialog), matching: find.byType(Material)));
|
|
||||||
final Material materialWidget = widget.state.widget;
|
|
||||||
expect(materialWidget.color, Colors.grey[800]);
|
expect(materialWidget.color, Colors.grey[800]);
|
||||||
expect(materialWidget.shape, _defaultDialogShape);
|
expect(materialWidget.shape, _defaultDialogShape);
|
||||||
|
expect(materialWidget.elevation, 24.0);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Custom dialog elevation', (WidgetTester tester) async {
|
||||||
|
const double customElevation = 12.0;
|
||||||
|
const AlertDialog dialog = AlertDialog(
|
||||||
|
actions: <Widget>[ ],
|
||||||
|
elevation: customElevation,
|
||||||
|
);
|
||||||
|
await tester.pumpWidget(_appWithAlertDialog(tester, dialog));
|
||||||
|
|
||||||
|
await tester.tap(find.text('X'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
final Material materialWidget = _getMaterialFromDialog(tester);
|
||||||
|
expect(materialWidget.elevation, customElevation);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Custom dialog shape', (WidgetTester tester) async {
|
testWidgets('Custom dialog shape', (WidgetTester tester) async {
|
||||||
@ -95,12 +126,9 @@ void main() {
|
|||||||
await tester.pumpWidget(_appWithAlertDialog(tester, dialog));
|
await tester.pumpWidget(_appWithAlertDialog(tester, dialog));
|
||||||
|
|
||||||
await tester.tap(find.text('X'));
|
await tester.tap(find.text('X'));
|
||||||
await tester.pump(); // start animation
|
await tester.pumpAndSettle();
|
||||||
await tester.pump(const Duration(seconds: 1));
|
|
||||||
|
|
||||||
final StatefulElement widget = tester.element(
|
final Material materialWidget = _getMaterialFromDialog(tester);
|
||||||
find.descendant(of: find.byType(AlertDialog), matching: find.byType(Material)));
|
|
||||||
final Material materialWidget = widget.state.widget;
|
|
||||||
expect(materialWidget.shape, customBorder);
|
expect(materialWidget.shape, customBorder);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -112,12 +140,9 @@ void main() {
|
|||||||
await tester.pumpWidget(_appWithAlertDialog(tester, dialog));
|
await tester.pumpWidget(_appWithAlertDialog(tester, dialog));
|
||||||
|
|
||||||
await tester.tap(find.text('X'));
|
await tester.tap(find.text('X'));
|
||||||
await tester.pump(); // start animation
|
await tester.pumpAndSettle();
|
||||||
await tester.pump(const Duration(seconds: 1));
|
|
||||||
|
|
||||||
final StatefulElement widget = tester.element(
|
final Material materialWidget = _getMaterialFromDialog(tester);
|
||||||
find.descendant(of: find.byType(AlertDialog), matching: find.byType(Material)));
|
|
||||||
final Material materialWidget = widget.state.widget;
|
|
||||||
expect(materialWidget.shape, _defaultDialogShape);
|
expect(materialWidget.shape, _defaultDialogShape);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -130,12 +155,9 @@ void main() {
|
|||||||
await tester.pumpWidget(_appWithAlertDialog(tester, dialog));
|
await tester.pumpWidget(_appWithAlertDialog(tester, dialog));
|
||||||
|
|
||||||
await tester.tap(find.text('X'));
|
await tester.tap(find.text('X'));
|
||||||
await tester.pump(); // start animation
|
await tester.pumpAndSettle();
|
||||||
await tester.pump(const Duration(seconds: 1));
|
|
||||||
|
|
||||||
final StatefulElement widget = tester.element(
|
final Material materialWidget = _getMaterialFromDialog(tester);
|
||||||
find.descendant(of: find.byType(AlertDialog), matching: find.byType(Material)));
|
|
||||||
final Material materialWidget = widget.state.widget;
|
|
||||||
expect(materialWidget.shape, customBorder);
|
expect(materialWidget.shape, customBorder);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -406,8 +428,7 @@ void main() {
|
|||||||
)));
|
)));
|
||||||
|
|
||||||
await tester.tap(find.text('X'));
|
await tester.tap(find.text('X'));
|
||||||
await tester.pump(); // start animation
|
await tester.pumpAndSettle();
|
||||||
await tester.pump(const Duration(seconds: 1));
|
|
||||||
|
|
||||||
expect(semantics, includesNodeWith(
|
expect(semantics, includesNodeWith(
|
||||||
label: 'Title',
|
label: 'Title',
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
import 'dart:io' show Platform;
|
import 'dart:io' show Platform;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
MaterialApp _appWithAlertDialog(WidgetTester tester, AlertDialog dialog, {ThemeData theme}) {
|
MaterialApp _appWithAlertDialog(WidgetTester tester, AlertDialog dialog, {ThemeData theme}) {
|
||||||
@ -34,7 +35,61 @@ MaterialApp _appWithAlertDialog(WidgetTester tester, AlertDialog dialog, {ThemeD
|
|||||||
|
|
||||||
final Key _painterKey = UniqueKey();
|
final Key _painterKey = UniqueKey();
|
||||||
|
|
||||||
|
Material _getMaterialFromDialog(WidgetTester tester) {
|
||||||
|
return tester.widget<Material>(find.descendant(of: find.byType(AlertDialog), matching: find.byType(Material)));
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
testWidgets('Dialog Theme implements debugFillDescription', (WidgetTester tester) async {
|
||||||
|
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
||||||
|
const DialogTheme(
|
||||||
|
backgroundColor: Color(0xff123456),
|
||||||
|
elevation: 8.0,
|
||||||
|
shape: null,
|
||||||
|
).debugFillProperties(builder);
|
||||||
|
final List<String> description = builder.properties
|
||||||
|
.where((DiagnosticsNode n) => !n.isFiltered(DiagnosticLevel.info))
|
||||||
|
.map((DiagnosticsNode n) => n.toString()).toList();
|
||||||
|
expect(description, <String>[
|
||||||
|
'backgroundColor: Color(0xff123456)',
|
||||||
|
'elevation: 8.0'
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Dialog background color', (WidgetTester tester) async {
|
||||||
|
const Color customColor = Colors.pink;
|
||||||
|
const AlertDialog dialog = AlertDialog(
|
||||||
|
title: Text('Title'),
|
||||||
|
actions: <Widget>[ ],
|
||||||
|
);
|
||||||
|
final ThemeData theme = ThemeData(dialogTheme: const DialogTheme(backgroundColor: customColor));
|
||||||
|
|
||||||
|
await tester.pumpWidget(_appWithAlertDialog(tester, dialog, theme: theme));
|
||||||
|
await tester.tap(find.text('X'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
final Material materialWidget = _getMaterialFromDialog(tester);
|
||||||
|
expect(materialWidget.color, customColor);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Custom dialog elevation', (WidgetTester tester) async {
|
||||||
|
const double customElevation = 12.0;
|
||||||
|
const AlertDialog dialog = AlertDialog(
|
||||||
|
title: Text('Title'),
|
||||||
|
actions: <Widget>[ ],
|
||||||
|
);
|
||||||
|
final ThemeData theme = ThemeData(dialogTheme: const DialogTheme(elevation: customElevation));
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
_appWithAlertDialog(tester, dialog, theme: theme)
|
||||||
|
);
|
||||||
|
await tester.tap(find.text('X'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
final Material materialWidget = _getMaterialFromDialog(tester);
|
||||||
|
expect(materialWidget.elevation, customElevation);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('Custom dialog shape', (WidgetTester tester) async {
|
testWidgets('Custom dialog shape', (WidgetTester tester) async {
|
||||||
const RoundedRectangleBorder customBorder =
|
const RoundedRectangleBorder customBorder =
|
||||||
RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0)));
|
RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0)));
|
||||||
@ -48,12 +103,9 @@ void main() {
|
|||||||
_appWithAlertDialog(tester, dialog, theme: theme)
|
_appWithAlertDialog(tester, dialog, theme: theme)
|
||||||
);
|
);
|
||||||
await tester.tap(find.text('X'));
|
await tester.tap(find.text('X'));
|
||||||
await tester.pump(); // start animation
|
await tester.pumpAndSettle();
|
||||||
await tester.pump(const Duration(seconds: 1));
|
|
||||||
|
|
||||||
final StatefulElement widget = tester.element(
|
final Material materialWidget = _getMaterialFromDialog(tester);
|
||||||
find.descendant(of: find.byType(AlertDialog), matching: find.byType(Material)));
|
|
||||||
final Material materialWidget = widget.state.widget;
|
|
||||||
expect(materialWidget.shape, customBorder);
|
expect(materialWidget.shape, customBorder);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user