Add clipBehavior to DrawerThemeData (#148061)

Fixes https://github.com/flutter/flutter/issues/148060
This commit is contained in:
Valentin Vignal 2024-05-16 02:37:07 +08:00 committed by GitHub
parent 8e35cf5125
commit ffae7c60c2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 42 additions and 6 deletions

View File

@ -11,7 +11,10 @@ class DrawerTemplate extends TokenTemplate {
String generate() => ''' String generate() => '''
class _${blockName}DefaultsM3 extends DrawerThemeData { class _${blockName}DefaultsM3 extends DrawerThemeData {
_${blockName}DefaultsM3(this.context) _${blockName}DefaultsM3(this.context)
: super(elevation: ${elevation("md.comp.navigation-drawer.modal.container")}); : super(
elevation: ${elevation("md.comp.navigation-drawer.modal.container")},
clipBehavior: Clip.hardEdge,
);
final BuildContext context; final BuildContext context;
late final TextDirection direction = Directionality.of(context); late final TextDirection direction = Directionality.of(context);

View File

@ -267,7 +267,7 @@ class Drawer extends StatelessWidget {
shadowColor: shadowColor ?? drawerTheme.shadowColor ?? defaults.shadowColor, shadowColor: shadowColor ?? drawerTheme.shadowColor ?? defaults.shadowColor,
surfaceTintColor: surfaceTintColor ?? drawerTheme.surfaceTintColor ?? defaults.surfaceTintColor, surfaceTintColor: surfaceTintColor ?? drawerTheme.surfaceTintColor ?? defaults.surfaceTintColor,
shape: effectiveShape, shape: effectiveShape,
clipBehavior: effectiveShape != null ? (clipBehavior ?? Clip.hardEdge) : Clip.none, clipBehavior: effectiveShape != null ? (clipBehavior ?? drawerTheme.clipBehavior ?? defaults.clipBehavior!) : Clip.none,
child: child, child: child,
), ),
), ),
@ -772,7 +772,10 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
class _DrawerDefaultsM2 extends DrawerThemeData { class _DrawerDefaultsM2 extends DrawerThemeData {
const _DrawerDefaultsM2(this.context) const _DrawerDefaultsM2(this.context)
: super(elevation: 16.0); : super(
elevation: 16.0,
clipBehavior: Clip.hardEdge,
);
final BuildContext context; final BuildContext context;
@ -790,7 +793,10 @@ class _DrawerDefaultsM2 extends DrawerThemeData {
class _DrawerDefaultsM3 extends DrawerThemeData { class _DrawerDefaultsM3 extends DrawerThemeData {
_DrawerDefaultsM3(this.context) _DrawerDefaultsM3(this.context)
: super(elevation: 1.0); : super(
elevation: 1.0,
clipBehavior: Clip.hardEdge,
);
final BuildContext context; final BuildContext context;
late final TextDirection direction = Directionality.of(context); late final TextDirection direction = Directionality.of(context);

View File

@ -43,6 +43,7 @@ class DrawerThemeData with Diagnosticable {
this.shape, this.shape,
this.endShape, this.endShape,
this.width, this.width,
this.clipBehavior,
}); });
/// Overrides the default value of [Drawer.backgroundColor]. /// Overrides the default value of [Drawer.backgroundColor].
@ -69,6 +70,9 @@ class DrawerThemeData with Diagnosticable {
/// Overrides the default value of [Drawer.width]. /// Overrides the default value of [Drawer.width].
final double? width; final double? width;
/// Overrides the default value of [Drawer.clipBehavior].
final Clip? clipBehavior;
/// Creates a copy of this object with the given fields replaced with the /// Creates a copy of this object with the given fields replaced with the
/// new values. /// new values.
DrawerThemeData copyWith({ DrawerThemeData copyWith({
@ -80,6 +84,7 @@ class DrawerThemeData with Diagnosticable {
ShapeBorder? shape, ShapeBorder? shape,
ShapeBorder? endShape, ShapeBorder? endShape,
double? width, double? width,
Clip? clipBehavior,
}) { }) {
return DrawerThemeData( return DrawerThemeData(
backgroundColor: backgroundColor ?? this.backgroundColor, backgroundColor: backgroundColor ?? this.backgroundColor,
@ -90,6 +95,7 @@ class DrawerThemeData with Diagnosticable {
shape: shape ?? this.shape, shape: shape ?? this.shape,
endShape: endShape ?? this.endShape, endShape: endShape ?? this.endShape,
width: width ?? this.width, width: width ?? this.width,
clipBehavior: clipBehavior ?? this.clipBehavior,
); );
} }
@ -111,6 +117,7 @@ class DrawerThemeData with Diagnosticable {
shape: ShapeBorder.lerp(a?.shape, b?.shape, t), shape: ShapeBorder.lerp(a?.shape, b?.shape, t),
endShape: ShapeBorder.lerp(a?.endShape, b?.endShape, t), endShape: ShapeBorder.lerp(a?.endShape, b?.endShape, t),
width: lerpDouble(a?.width, b?.width, t), width: lerpDouble(a?.width, b?.width, t),
clipBehavior: t < 0.5 ? a?.clipBehavior : b?.clipBehavior,
); );
} }
@ -124,6 +131,7 @@ class DrawerThemeData with Diagnosticable {
shape, shape,
endShape, endShape,
width, width,
clipBehavior,
); );
@override @override
@ -142,7 +150,8 @@ class DrawerThemeData with Diagnosticable {
&& other.surfaceTintColor == surfaceTintColor && other.surfaceTintColor == surfaceTintColor
&& other.shape == shape && other.shape == shape
&& other.endShape == endShape && other.endShape == endShape
&& other.width == width; && other.width == width
&& other.clipBehavior == clipBehavior;
} }
@override @override
@ -156,6 +165,7 @@ class DrawerThemeData with Diagnosticable {
properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null)); properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
properties.add(DiagnosticsProperty<ShapeBorder>('endShape', endShape, defaultValue: null)); properties.add(DiagnosticsProperty<ShapeBorder>('endShape', endShape, defaultValue: null));
properties.add(DoubleProperty('width', width, defaultValue: null)); properties.add(DoubleProperty('width', width, defaultValue: null));
properties.add(DiagnosticsProperty<Clip>('clipBehavior', clipBehavior, defaultValue: null));
} }
} }

View File

@ -40,6 +40,7 @@ void main() {
surfaceTintColor: Color(0x00000096), surfaceTintColor: Color(0x00000096),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0))), shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0))),
width: 200.0, width: 200.0,
clipBehavior: Clip.hardEdge,
).debugFillProperties(builder); ).debugFillProperties(builder);
final List<String> description = builder.properties final List<String> description = builder.properties
@ -55,6 +56,7 @@ void main() {
'surfaceTintColor: Color(0x00000096)', 'surfaceTintColor: Color(0x00000096)',
'shape: RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.circular(2.0))', 'shape: RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.circular(2.0))',
'width: 200.0', 'width: 200.0',
'clipBehavior: Clip.hardEdge',
]); ]);
}); });
@ -80,6 +82,7 @@ void main() {
expect(_drawerMaterial(tester).shape, null); expect(_drawerMaterial(tester).shape, null);
expect(_scrim(tester).color, Colors.black54); expect(_scrim(tester).color, Colors.black54);
expect(_drawerRenderBox(tester).size.width, 304.0); expect(_drawerRenderBox(tester).size.width, 304.0);
expect(_drawerMaterial(tester).clipBehavior, Clip.none);
}); });
testWidgets('Material3 - Default values are used when no Drawer or DrawerThemeData properties are specified', (WidgetTester tester) async { testWidgets('Material3 - Default values are used when no Drawer or DrawerThemeData properties are specified', (WidgetTester tester) async {
@ -107,6 +110,7 @@ void main() {
); );
expect(_scrim(tester).color, Colors.black54); expect(_scrim(tester).color, Colors.black54);
expect(_drawerRenderBox(tester).size.width, 304.0); expect(_drawerRenderBox(tester).size.width, 304.0);
expect(_drawerMaterial(tester).clipBehavior, Clip.hardEdge);
}); });
testWidgets('Material2 - Default values are used when no Drawer or DrawerThemeData properties are specified in end drawer', (WidgetTester tester) async { testWidgets('Material2 - Default values are used when no Drawer or DrawerThemeData properties are specified in end drawer', (WidgetTester tester) async {
@ -131,6 +135,7 @@ void main() {
expect(_drawerMaterial(tester).shape, null); expect(_drawerMaterial(tester).shape, null);
expect(_scrim(tester).color, Colors.black54); expect(_scrim(tester).color, Colors.black54);
expect(_drawerRenderBox(tester).size.width, 304.0); expect(_drawerRenderBox(tester).size.width, 304.0);
expect(_drawerMaterial(tester).clipBehavior, Clip.none);
}); });
testWidgets('Material3 - Default values are used when no Drawer or DrawerThemeData properties are specified in end drawer', (WidgetTester tester) async { testWidgets('Material3 - Default values are used when no Drawer or DrawerThemeData properties are specified in end drawer', (WidgetTester tester) async {
@ -158,6 +163,7 @@ void main() {
); );
expect(_scrim(tester).color, Colors.black54); expect(_scrim(tester).color, Colors.black54);
expect(_drawerRenderBox(tester).size.width, 304.0); expect(_drawerRenderBox(tester).size.width, 304.0);
expect(_drawerMaterial(tester).clipBehavior, Clip.hardEdge);
}); });
testWidgets('DrawerThemeData values are used when no Drawer properties are specified', (WidgetTester tester) async { testWidgets('DrawerThemeData values are used when no Drawer properties are specified', (WidgetTester tester) async {
@ -168,6 +174,7 @@ void main() {
const Color surfaceTintColor = Color(0x00000004); const Color surfaceTintColor = Color(0x00000004);
const RoundedRectangleBorder shape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0))); const RoundedRectangleBorder shape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0)));
const double width = 200.0; const double width = 200.0;
const Clip clipBehavior = Clip.antiAlias;
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
await tester.pumpWidget( await tester.pumpWidget(
@ -181,6 +188,7 @@ void main() {
surfaceTintColor: surfaceTintColor, surfaceTintColor: surfaceTintColor,
shape: shape, shape: shape,
width: width, width: width,
clipBehavior: clipBehavior,
), ),
), ),
home: Scaffold( home: Scaffold(
@ -199,6 +207,7 @@ void main() {
expect(_drawerMaterial(tester).shape, shape); expect(_drawerMaterial(tester).shape, shape);
expect(_scrim(tester).color, scrimColor); expect(_scrim(tester).color, scrimColor);
expect(_drawerRenderBox(tester).size.width, width); expect(_drawerRenderBox(tester).size.width, width);
expect(_drawerMaterial(tester).clipBehavior, clipBehavior);
}); });
testWidgets('Drawer values take priority over DrawerThemeData values when both properties are specified', (WidgetTester tester) async { testWidgets('Drawer values take priority over DrawerThemeData values when both properties are specified', (WidgetTester tester) async {
@ -209,6 +218,7 @@ void main() {
const Color surfaceTintColor = Color(0x00000004); const Color surfaceTintColor = Color(0x00000004);
const RoundedRectangleBorder shape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0))); const RoundedRectangleBorder shape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0)));
const double width = 200.0; const double width = 200.0;
const Clip clipBehavior = Clip.antiAlias;
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
await tester.pumpWidget( await tester.pumpWidget(
@ -220,6 +230,7 @@ void main() {
elevation: 13.0, elevation: 13.0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(29.0))), shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(29.0))),
width: 400.0, width: 400.0,
clipBehavior: Clip.antiAliasWithSaveLayer,
), ),
), ),
home: Scaffold( home: Scaffold(
@ -232,6 +243,7 @@ void main() {
surfaceTintColor: surfaceTintColor, surfaceTintColor: surfaceTintColor,
shape: shape, shape: shape,
width: width, width: width,
clipBehavior: clipBehavior,
), ),
), ),
), ),
@ -246,6 +258,7 @@ void main() {
expect(_drawerMaterial(tester).shape, shape); expect(_drawerMaterial(tester).shape, shape);
expect(_scrim(tester).color, scrimColor); expect(_scrim(tester).color, scrimColor);
expect(_drawerRenderBox(tester).size.width, width); expect(_drawerRenderBox(tester).size.width, width);
expect(_drawerMaterial(tester).clipBehavior, clipBehavior);
}); });
testWidgets('DrawerTheme values take priority over ThemeData.drawerTheme values when both properties are specified', (WidgetTester tester) async { testWidgets('DrawerTheme values take priority over ThemeData.drawerTheme values when both properties are specified', (WidgetTester tester) async {
@ -256,6 +269,7 @@ void main() {
const Color surfaceTintColor = Color(0x00000004); const Color surfaceTintColor = Color(0x00000004);
const RoundedRectangleBorder shape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0))); const RoundedRectangleBorder shape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0)));
const double width = 200.0; const double width = 200.0;
const Clip clipBehavior = Clip.antiAlias;
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
await tester.pumpWidget( await tester.pumpWidget(
@ -268,7 +282,8 @@ void main() {
shadowColor: Color(0x00000007), shadowColor: Color(0x00000007),
surfaceTintColor: Color(0x00000007), surfaceTintColor: Color(0x00000007),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(29.0))), shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(29.0))),
width: 400.0 width: 400.0,
clipBehavior: Clip.antiAliasWithSaveLayer,
), ),
), ),
home: DrawerTheme( home: DrawerTheme(
@ -280,6 +295,7 @@ void main() {
surfaceTintColor: surfaceTintColor, surfaceTintColor: surfaceTintColor,
shape: shape, shape: shape,
width: width, width: width,
clipBehavior: clipBehavior,
), ),
child: Scaffold( child: Scaffold(
key: scaffoldKey, key: scaffoldKey,
@ -298,6 +314,7 @@ void main() {
expect(_drawerMaterial(tester).shape, shape); expect(_drawerMaterial(tester).shape, shape);
expect(_scrim(tester).color, scrimColor); expect(_scrim(tester).color, scrimColor);
expect(_drawerRenderBox(tester).size.width, width); expect(_drawerRenderBox(tester).size.width, width);
expect(_drawerMaterial(tester).clipBehavior, clipBehavior);
}); });
} }