Render Material using a PhysicalModel with optional compositing (#8920)
This commit is contained in:
parent
09b6850499
commit
8aa4314930
@ -7,7 +7,6 @@ import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'constants.dart';
|
||||
import 'shadows.dart';
|
||||
import 'theme.dart';
|
||||
|
||||
/// Signature for the callback used by ink effects to obtain the rectangle for the effect.
|
||||
@ -228,14 +227,33 @@ class _MaterialState extends State<Material> with TickerProviderStateMixin {
|
||||
vsync: this,
|
||||
)
|
||||
);
|
||||
|
||||
if (config.type == MaterialType.circle) {
|
||||
contents = new ClipOval(child: contents);
|
||||
} else if (kMaterialEdges[config.type] != null) {
|
||||
contents = new ClipRRect(
|
||||
borderRadius: radius,
|
||||
child: contents
|
||||
contents = new PhysicalModel(
|
||||
shape: BoxShape.circle,
|
||||
elevation: config.elevation,
|
||||
color: backgroundColor,
|
||||
child: contents,
|
||||
);
|
||||
} else if (config.type == MaterialType.transparency) {
|
||||
if (radius == null) {
|
||||
contents = new ClipRect(child: contents);
|
||||
} else {
|
||||
contents = new ClipRRect(
|
||||
borderRadius: radius,
|
||||
child: contents
|
||||
);
|
||||
}
|
||||
} else {
|
||||
contents = new PhysicalModel(
|
||||
shape: BoxShape.rectangle,
|
||||
borderRadius: radius ?? BorderRadius.zero,
|
||||
elevation: config.elevation,
|
||||
color: backgroundColor,
|
||||
child: contents,
|
||||
);
|
||||
}
|
||||
|
||||
if (config.type != MaterialType.transparency) {
|
||||
contents = new AnimatedContainer(
|
||||
curve: Curves.fastOutSlowIn,
|
||||
@ -247,7 +265,6 @@ class _MaterialState extends State<Material> with TickerProviderStateMixin {
|
||||
child: new Container(
|
||||
decoration: new BoxDecoration(
|
||||
borderRadius: radius,
|
||||
boxShadow: config.elevation == 0 ? null : kElevationToShadow[config.elevation],
|
||||
backgroundColor: backgroundColor,
|
||||
shape: config.type == MaterialType.circle ? BoxShape.circle : BoxShape.rectangle
|
||||
),
|
||||
|
@ -442,19 +442,35 @@ class PaintingContext {
|
||||
/// * `color` is the background color.
|
||||
/// * `painter` is a callback that will paint with the `clipRRect` applied. This
|
||||
/// function calls the `painter` synchronously.
|
||||
void pushPhysicalModel(Offset offset, Rect bounds, RRect clipRRect, int elevation, Color color, PaintingContextCallback painter) {
|
||||
void pushPhysicalModel(bool needsCompositing, Offset offset, Rect bounds, RRect clipRRect, int elevation, Color color, PaintingContextCallback painter) {
|
||||
final Rect offsetBounds = bounds.shift(offset);
|
||||
final RRect offsetClipRRect = clipRRect.shift(offset);
|
||||
_stopRecordingIfNeeded();
|
||||
final PhysicalModelLayer physicalModel = new PhysicalModelLayer(
|
||||
clipRRect: offsetClipRRect,
|
||||
elevation: elevation,
|
||||
color: color,
|
||||
);
|
||||
_appendLayer(physicalModel);
|
||||
final PaintingContext childContext = new PaintingContext._(physicalModel, offsetBounds);
|
||||
painter(childContext, offset);
|
||||
childContext._stopRecordingIfNeeded();
|
||||
if (needsCompositing) {
|
||||
_stopRecordingIfNeeded();
|
||||
final PhysicalModelLayer physicalModel = new PhysicalModelLayer(
|
||||
clipRRect: offsetClipRRect,
|
||||
elevation: elevation,
|
||||
color: color,
|
||||
);
|
||||
_appendLayer(physicalModel);
|
||||
final PaintingContext childContext = new PaintingContext._(physicalModel, offsetBounds);
|
||||
painter(childContext, offset);
|
||||
childContext._stopRecordingIfNeeded();
|
||||
} else {
|
||||
if (elevation != 0) {
|
||||
canvas.drawShadow(
|
||||
new Path()..addRRect(offsetClipRRect),
|
||||
const Color(0xFF000000),
|
||||
elevation,
|
||||
color.alpha != 0xFF,
|
||||
);
|
||||
}
|
||||
canvas.drawRRect(offsetClipRRect, new Paint()..color=color);
|
||||
canvas.saveLayer(offsetBounds, _defaultPaint);
|
||||
canvas.clipRRect(offsetClipRRect);
|
||||
painter(this, offset);
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1210,9 +1210,6 @@ class RenderPhysicalModel extends _RenderCustomClip<RRect> {
|
||||
assert(_borderRadius != null);
|
||||
}
|
||||
|
||||
@override
|
||||
bool get alwaysNeedsCompositing => true;
|
||||
|
||||
/// The shape of the layer.
|
||||
BoxShape get shape => _shape;
|
||||
BoxShape _shape;
|
||||
@ -1285,7 +1282,7 @@ class RenderPhysicalModel extends _RenderCustomClip<RRect> {
|
||||
void paint(PaintingContext context, Offset offset) {
|
||||
if (child != null) {
|
||||
_updateClip();
|
||||
context.pushPhysicalModel(offset, _clip.outerRect, _clip, _elevation, _color, super.paint);
|
||||
context.pushPhysicalModel(needsCompositing, offset, _clip.outerRect, _clip, _elevation, _color, super.paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user