mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
CustomPaint size (#6790)
This commit is contained in:
parent
01a8d51022
commit
fcd47f84d2
@ -1783,17 +1783,27 @@ abstract class CustomPainter {
|
||||
/// tree as needing a new layout during the callback (the layout for this frame
|
||||
/// has already happened).
|
||||
///
|
||||
/// Custom painters normally size themselves to their child. If they do not have
|
||||
/// a child, they attempt to size themselves to the [preferredSize], which
|
||||
/// defaults to [Size.zero].
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [CustomPainter]
|
||||
/// * [Canvas]
|
||||
/// * [CustomPainter], the class that custom painter delegates should extend.
|
||||
/// * [Canvas], the API provided to custom painter delegates.
|
||||
class RenderCustomPaint extends RenderProxyBox {
|
||||
/// Creates a render object that delegates its painting.
|
||||
RenderCustomPaint({
|
||||
CustomPainter painter,
|
||||
CustomPainter foregroundPainter,
|
||||
RenderBox child
|
||||
}) : _painter = painter, _foregroundPainter = foregroundPainter, super(child);
|
||||
Size preferredSize: Size.zero,
|
||||
RenderBox child,
|
||||
}) : _painter = painter,
|
||||
_foregroundPainter = foregroundPainter,
|
||||
_preferredSize = preferredSize,
|
||||
super(child) {
|
||||
assert(preferredSize != null);
|
||||
}
|
||||
|
||||
/// The background custom paint delegate.
|
||||
///
|
||||
@ -1860,6 +1870,23 @@ class RenderCustomPaint extends RenderProxyBox {
|
||||
}
|
||||
}
|
||||
|
||||
/// The size that this [RenderCustomPaint] should aim for, given the layout
|
||||
/// constraints, if there is no child.
|
||||
///
|
||||
/// Defaults to [Size.zero].
|
||||
///
|
||||
/// If there's a child, this is ignored, and the size of the child is used
|
||||
/// instead.
|
||||
Size get preferredSize => _preferredSize;
|
||||
Size _preferredSize;
|
||||
set preferredSize (Size value) {
|
||||
assert(value != null);
|
||||
if (preferredSize == value)
|
||||
return;
|
||||
_preferredSize = value;
|
||||
markNeedsLayout();
|
||||
}
|
||||
|
||||
@override
|
||||
void attach(PipelineOwner owner) {
|
||||
super.attach(owner);
|
||||
@ -1886,6 +1913,11 @@ class RenderCustomPaint extends RenderProxyBox {
|
||||
return _painter != null && (_painter.hitTest(position) ?? true);
|
||||
}
|
||||
|
||||
@override
|
||||
void performResize() {
|
||||
size = constraints.constrain(preferredSize);
|
||||
}
|
||||
|
||||
void _paintWithPainter(Canvas canvas, Offset offset, CustomPainter painter) {
|
||||
int debugPreviousCanvasSaveCount;
|
||||
canvas.save();
|
||||
|
||||
@ -197,9 +197,13 @@ class BackdropFilter extends SingleChildRenderObjectWidget {
|
||||
///
|
||||
/// Painters are implemented by subclassing [CustomPainter].
|
||||
///
|
||||
/// Because custom paint calls its painters during paint, you cannot mark the
|
||||
/// tree as needing a new layout during the callback (the layout for this frame
|
||||
/// has already happened).
|
||||
/// Because custom paint calls its painters during paint, you cannot call
|
||||
/// `setState` or `markNeedsLayout` during the callback (the layout for this
|
||||
/// frame has already happened).
|
||||
///
|
||||
/// Custom painters normally size themselves to their child. If they do not have
|
||||
/// a child, they attempt to size themselves to the [size], which defaults to
|
||||
/// [Size.zero].
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
@ -207,8 +211,10 @@ class BackdropFilter extends SingleChildRenderObjectWidget {
|
||||
/// * [Canvas].
|
||||
class CustomPaint extends SingleChildRenderObjectWidget {
|
||||
/// Creates a widget that delegates its painting.
|
||||
CustomPaint({ Key key, this.painter, this.foregroundPainter, Widget child })
|
||||
: super(key: key, child: child);
|
||||
CustomPaint({ Key key, this.painter, this.foregroundPainter, this.size: Size.zero, Widget child })
|
||||
: super(key: key, child: child) {
|
||||
assert(size != null);
|
||||
}
|
||||
|
||||
/// The painter that paints before the children.
|
||||
final CustomPainter painter;
|
||||
@ -216,17 +222,28 @@ class CustomPaint extends SingleChildRenderObjectWidget {
|
||||
/// The painter that paints after the children.
|
||||
final CustomPainter foregroundPainter;
|
||||
|
||||
/// The size that this [CustomPaint] should aim for, given the layout
|
||||
/// constraints, if there is no child.
|
||||
///
|
||||
/// Defaults to [Size.zero].
|
||||
///
|
||||
/// If there's a child, this is ignored, and the size of the child is used
|
||||
/// instead.
|
||||
final Size size;
|
||||
|
||||
@override
|
||||
RenderCustomPaint createRenderObject(BuildContext context) => new RenderCustomPaint(
|
||||
painter: painter,
|
||||
foregroundPainter: foregroundPainter
|
||||
foregroundPainter: foregroundPainter,
|
||||
preferredSize: size,
|
||||
);
|
||||
|
||||
@override
|
||||
void updateRenderObject(BuildContext context, RenderCustomPaint renderObject) {
|
||||
renderObject
|
||||
..painter = painter
|
||||
..foregroundPainter = foregroundPainter;
|
||||
..foregroundPainter = foregroundPainter
|
||||
..preferredSize = size;
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@ -42,4 +42,39 @@ void main() {
|
||||
|
||||
expect(log, equals(<String>['background', 'child', 'foreground']));
|
||||
});
|
||||
|
||||
testWidgets('CustomPaint sizing', (WidgetTester tester) async {
|
||||
GlobalKey target = new GlobalKey();
|
||||
|
||||
await tester.pumpWidget(new Center(
|
||||
child: new CustomPaint(key: target)
|
||||
));
|
||||
expect(target.currentContext.size, Size.zero);
|
||||
|
||||
await tester.pumpWidget(new Center(
|
||||
child: new CustomPaint(key: target, child: new Container())
|
||||
));
|
||||
expect(target.currentContext.size, const Size(800.0, 600.0));
|
||||
|
||||
await tester.pumpWidget(new Center(
|
||||
child: new CustomPaint(key: target, size: const Size(20.0, 20.0))
|
||||
));
|
||||
expect(target.currentContext.size, const Size(20.0, 20.0));
|
||||
|
||||
await tester.pumpWidget(new Center(
|
||||
child: new CustomPaint(key: target, size: const Size(2000.0, 100.0))
|
||||
));
|
||||
expect(target.currentContext.size, const Size(800.0, 100.0));
|
||||
|
||||
await tester.pumpWidget(new Center(
|
||||
child: new CustomPaint(key: target, size: Size.zero, child: new Container())
|
||||
));
|
||||
expect(target.currentContext.size, const Size(800.0, 600.0));
|
||||
|
||||
await tester.pumpWidget(new Center(
|
||||
child: new CustomPaint(key: target, child: new Container(height: 0.0, width: 0.0))
|
||||
));
|
||||
expect(target.currentContext.size, Size.zero);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user