flutter RenderObject中parentUsesS
2020-03-03 本文已影响0人
liboxiang
测试代码
double SizeOne = 30;
double SizeTwo = 30;
Column(
children: <Widget>[
CustomConstrainedBox(
child: StatefulBuilder(builder: (_, refresh) {
return Tint(
color: Colors.yellow,
child: Container(
color: Colors.red,
width: SizeOne,
height: SizeOne,
child: MaterialButton(
child: Text('refresh'),
onPressed: () {
refresh(() {
SizeOne = SizeOne + 5;
});
}),
),
);
}),
constraints: BoxConstraints(),
),
ConstrainedBox(
child: StatefulBuilder(builder: (_, refresh) {
return Tint(
color: Colors.yellow,
child: Container(
color: Colors.blue,
width: SizeTwo,
height: SizeTwo,
child: MaterialButton(
child: Text('refresh'),
onPressed: () {
refresh(() {
SizeTwo = SizeTwo + 5;
});
}),
),
);
}),
constraints: BoxConstraints(),
),
Container(
height: 30,
color: Colors.yellow,
),
],
)
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
//拷贝ConstrainedBox修改,不同之处为对应的RenderObject中
//child.layout(Constraints constraints, { bool parentUsesSize = false })
//parentUsesSize传值false,ConstrainedBox中对应的RenderObject的
//child.layou方法parentUsesSize传值true
class CustomConstrainedBox extends SingleChildRenderObjectWidget {
/// Creates a widget that imposes additional constraints on its child.
///
/// The [constraints] argument must not be null.
CustomConstrainedBox({
Key key,
@required this.constraints,
Widget child,
}) : assert(constraints != null),
assert(constraints.debugAssertIsValid()),
super(key: key, child: child);
/// The additional constraints to impose on the child.
final BoxConstraints constraints;
@override
CustomRenderConstrainedBox createRenderObject(BuildContext context) {
return CustomRenderConstrainedBox(additionalConstraints: constraints);
}
@override
void updateRenderObject(
BuildContext context, CustomRenderConstrainedBox renderObject) {
renderObject.additionalConstraints = constraints;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<BoxConstraints>(
'constraints', constraints,
showName: false));
}
}
class CustomRenderConstrainedBox extends RenderConstrainedBox {
CustomRenderConstrainedBox({
RenderBox child,
@required BoxConstraints additionalConstraints,
}) : assert(additionalConstraints != null),
assert(additionalConstraints.debugAssertIsValid()),
super(child:child,additionalConstraints:additionalConstraints);
@override
void performLayout() {
if (child != null) {
child.layout(additionalConstraints.enforce(constraints),
parentUsesSize: false);
size = Size.copy(child.size);
} else {
size = additionalConstraints.enforce(constraints).constrain(Size.zero);
}
}
}
class Tint extends SingleChildRenderObjectWidget {
const Tint({
Key key,
@required this.color,
Widget child,
}) : assert(color != null),
super(key: key, child: child);
final Color color;
@override
RenderTint createRenderObject(BuildContext context) {
return RenderTint(
color: color,
);
}
@override
void updateRenderObject(BuildContext context, RenderTint renderObject) {
renderObject
..color = color;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(ColorProperty('color', color));
}
}
class RenderTint extends RenderProxyBox {
RenderTint({
Color color = Colors.transparent,
RenderBox child,
}) : assert(color != null),
_color = color,
super(child);
Color get color => _color;
Color _color;
set color(Color color) {
assert(color != null);
if (_color == color) return;
_color = color;
markNeedsPaint();
markNeedsSemanticsUpdate();
}
@override
void paint(PaintingContext context, Offset offset) {
if (child != null) {
context.paintChild(child, offset);
}
// context.canvas.drawColor(color, BlendMode.srcOver);
}
@override
// TODO: implement debugDoingThisResize
bool get debugDoingThisResize => false;
@override
// TODO: implement debugDoingThisLayout
bool get debugDoingThisLayout => true;
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(ColorProperty('color', color));
}
}
效果图如下:
WeChateaa1f2a9cf4d061c90b1eda1e9ecb7fe.png两个颜色块都点击放大之后如下图所示:
WeChat4a5b28586330ad5804a3b5f8eaec3244.png
结论
- ConstrainedBox的RenderObject中child.layou方法parentUsesSize传值true,则ConstrainedBox的child(蓝色块)变大的时候,ConstrainedBox会重新layout,从而影响到Column增加高度。
- CustomConstrainedBox的RenderObject中child.layou方法parentUsesSize传值false,则CustomConstrainedBox的child(红色块)变大的时候,CustomConstrainedBox不会会重新layout,从而不会影响Column,同时点击红色块增产出来的部分没有效果,因为点击point超出CustomConstrainedBox的大小范围了,hitTest没响应。