From 27cc8c06b2a83b3ad6a4448b6e18045ddefc2d3c Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Wed, 21 Apr 2021 13:29:06 -0700 Subject: [PATCH] Move ExpansionPanelList to Canvas.drawShadow (#80134) --- .../lib/src/material/mergeable_material.dart | 57 +++++++++---------- .../material/mergeable_material_test.dart | 5 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/packages/flutter/lib/src/material/mergeable_material.dart b/packages/flutter/lib/src/material/mergeable_material.dart index 1f93adf09e..c05252887c 100644 --- a/packages/flutter/lib/src/material/mergeable_material.dart +++ b/packages/flutter/lib/src/material/mergeable_material.dart @@ -7,9 +7,9 @@ import 'dart:ui' show lerpDouble; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; +import 'colors.dart'; import 'divider.dart'; import 'material.dart'; -import 'shadows.dart'; import 'theme.dart'; /// The base type for [MaterialSlice] and [MaterialGap]. @@ -122,12 +122,8 @@ class MergeableMaterial extends StatefulWidget { /// The z-coordinate at which to place all the [Material] slices. /// - /// The following elevations have defined shadows: 1, 2, 3, 4, 6, 8, 9, 12, 16, 24. - /// /// Defaults to 2, the appropriate elevation for cards. - /// - /// This uses [kElevationToShadow] to simulate shadows, it does not use - /// [Material]'s arbitrary elevation feature. + // TODO(ianh): Change this to double. final int elevation; /// Whether connected pieces of [MaterialSlice] have dividers between them. @@ -620,7 +616,7 @@ class _MergeableMaterialState extends State with TickerProvid return _MergeableMaterialListBody( mainAxis: widget.mainAxis, - boxShadows: kElevationToShadow[widget.elevation]!, + elevation: widget.elevation.toDouble(), items: _children, children: widgets, ); @@ -654,11 +650,11 @@ class _MergeableMaterialListBody extends ListBody { required List children, Axis mainAxis = Axis.vertical, required this.items, - required this.boxShadows, + required this.elevation, }) : super(children: children, mainAxis: mainAxis); final List items; - final List boxShadows; + final double elevation; AxisDirection _getDirection(BuildContext context) { return getAxisDirectionFromAxisReverseAndDirectionality(context, mainAxis, false); @@ -668,7 +664,7 @@ class _MergeableMaterialListBody extends ListBody { RenderListBody createRenderObject(BuildContext context) { return _RenderMergeableMaterialListBody( axisDirection: _getDirection(context), - boxShadows: boxShadows, + elevation: elevation, ); } @@ -677,7 +673,7 @@ class _MergeableMaterialListBody extends ListBody { final _RenderMergeableMaterialListBody materialRenderListBody = renderObject as _RenderMergeableMaterialListBody; materialRenderListBody ..axisDirection = _getDirection(context) - ..boxShadows = boxShadows; + ..elevation = elevation; } } @@ -685,38 +681,41 @@ class _RenderMergeableMaterialListBody extends RenderListBody { _RenderMergeableMaterialListBody({ List? children, AxisDirection axisDirection = AxisDirection.down, - required this.boxShadows, - }) : super(children: children, axisDirection: axisDirection); + double elevation = 0.0, + }) : _elevation = elevation, + super(children: children, axisDirection: axisDirection); - List boxShadows; + double get elevation => _elevation; + double _elevation; + set elevation(double value) { + if (value == _elevation) + return; + _elevation = value; + markNeedsPaint(); + } void _paintShadows(Canvas canvas, Rect rect) { - for (final BoxShadow boxShadow in boxShadows) { - final Paint paint = boxShadow.toPaint(); - // TODO(dragostis): Right now, we are only interpolating the border radii - // of the visible Material slices, not the shadows; they are not getting - // interpolated and always have the same rounded radii. Once shadow - // performance is better, shadows should be redrawn every single time the - // slices' radii get interpolated and use those radii not the defaults. - canvas.drawRRect(kMaterialEdges[MaterialType.card]!.toRRect(rect), paint); - } + // TODO(ianh): We should interpolate the border radii of the shadows the same way we do those of the visible Material slices. + canvas.drawShadow( + Path()..addRRect(kMaterialEdges[MaterialType.card]!.toRRect(rect)), + Colors.black, + elevation, + true, // occluding object is not (necessarily) opaque + ); } @override void paint(PaintingContext context, Offset offset) { RenderBox? child = firstChild; - int i = 0; - + int index = 0; while (child != null) { final ListBodyParentData childParentData = child.parentData! as ListBodyParentData; final Rect rect = (childParentData.offset + offset) & child.size; - if (i.isEven) + if (index.isEven) _paintShadows(context.canvas, rect); child = childParentData.nextSibling; - - i += 1; + index += 1; } - defaultPaint(context, offset); } } diff --git a/packages/flutter/test/material/mergeable_material_test.dart b/packages/flutter/test/material/mergeable_material_test.dart index c9f69ed0b8..913a891520 100644 --- a/packages/flutter/test/material/mergeable_material_test.dart +++ b/packages/flutter/test/material/mergeable_material_test.dart @@ -221,13 +221,14 @@ void main() { ), ); - final BoxShadow boxShadow = kElevationToShadow[2]![0]; final RRect rrect = kMaterialEdges[MaterialType.card]!.toRRect( const Rect.fromLTRB(0.0, 0.0, 800.0, 100.0) ); expect( find.byType(MergeableMaterial), - paints..rrect(rrect: rrect, color: boxShadow.color, hasMaskFilter: true), + paints + ..shadow(elevation: 2.0) + ..rrect(rrect: rrect, color: Colors.white, hasMaskFilter: false), ); debugDisableShadows = true; });