深色模式
RenderImage 源码分析
RenderImage
介绍
渲染图片。
dart
class RenderImage extends RenderBox {
//...
}
_image _width _height
这些是与图片组件相关的参数,有很多个,略过,这里只分析布局、绘制的逻辑。
_sizeForConstraints()
作用:
计算在给定约束条件下图片的最终渲染尺寸,同时需要满足三个主要条件:
- 尺寸必须符合约束条件
- 保持图片原有的宽高比
- 在满足前两个条件的情况下尽可能取最大尺寸
代码分析:
dart
Size _sizeForConstraints(BoxConstraints constraints) {
constraints = BoxConstraints.tightFor(
width: _width,
height: _height,
).enforce(constraints);
if (_image == null) {
return constraints.smallest;
}
return constraints.constrainSizeAndAttemptToPreserveAspectRatio(Size(
_image!.width.toDouble() / _scale,
_image!.height.toDouble() / _scale,
));
}
dart
Size _sizeForConstraints(BoxConstraints constraints) {
constraints = BoxConstraints.tightFor(
width: _width,
height: _height,
).enforce(constraints);
if (_image == null) {
return constraints.smallest;
}
return constraints.constrainSizeAndAttemptToPreserveAspectRatio(Size(
_image!.width.toDouble() / _scale,
_image!.height.toDouble() / _scale,
));
}
dart
Size _sizeForConstraints(BoxConstraints constraints) {
constraints = BoxConstraints.tightFor(
width: _width,
height: _height,
).enforce(constraints);
if (_image == null) {
return constraints.smallest;
}
return constraints.constrainSizeAndAttemptToPreserveAspectRatio(Size(
_image!.width.toDouble() / _scale,
_image!.height.toDouble() / _scale,
));
}
这个方法被后面多个方法调用。
computeMinIntrinsicWidth()
调用 _sizeForConstraints()
,下同
computeMaxIntrinsicWidth()
computeMinIntrinsicHeight()
computeMaxIntrinsicHeight()
hitTestSelf()
dart
@override
bool hitTestSelf(Offset position) => true;
computeDryLayout()
dart
@override
@protected
Size computeDryLayout(covariant BoxConstraints constraints) {
return _sizeForConstraints(constraints);
}
调用 _sizeForConstraints()
performLayout()
代码:
dart
@override
void performLayout() {
size = _sizeForConstraints(constraints);
}
分析:
图片渲染对象的大小,受到图片内容的影响,所以要在 performLayout()
中计算 size
。
attach()
dart
@override
void attach(covariant PipelineOwner owner) {
super.attach(owner);
_opacity?.addListener(markNeedsPaint);
}
添加监听,当透明度变化时,触发重绘。
detach()
dart
@override
void detach() {
_opacity?.removeListener(markNeedsPaint);
super.detach();
}
移除监听
paint()
dart
@override
void paint(PaintingContext context, Offset offset) {
if (_image == null) {
return;
}
_resolve();
assert(_resolvedAlignment != null);
assert(_flipHorizontally != null);
paintImage(
canvas: context.canvas,
rect: offset & size,
image: _image!,
...
);
}
调用paintImage()
函数,绘制图片,这是一个定义在flutter/src/painting/
中的顶级函数。
dispose()
dart
@override
void dispose() {
_image?.dispose();
_image = null;
super.dispose();
}
释放ui.Image
资源