flutter - 如何在屏幕外绘制 Flutter Widget
问题描述
我正在寻找一种解决方案,以在永远不会显示在屏幕上的单独图形管道中绘制 Flutter Widget 树。无论显示器如何,我都希望能够将宽度/高度约束定义为任何尺寸。目标是获取此 Widget 的不依赖于设备的 png 图像,并将其发送到打印机。我知道可以RepaintBundary
用来构建图像,但这仅适用于屏幕上显示的内容。
我测试了这样的东西,没有运气:
Future<void> capture(BuildContext context, Widget widget) async {
final rect = Rect.fromLTWH(0, 0, 200, 200);
final root = OffscreenPainter(
size: Size(200, 200),
child: ConstrainedBox(
constraints: BoxConstraints.tightFor(width: 200, height: 200),
child: widget,
));
final ro = root.createRenderObject(context);
final el = root.createElement();
// el.activate();
el.attachRenderObject(ro);
final o = PipelineOwner();
// ro.attach(o);
o.rootNode = ro;
ro.scheduleInitialLayout();
final rootLayer = OffsetLayer();
rootLayer.attach(o);
ro.scheduleInitialPaint(rootLayer);
el.updateChildren();
ro.layout(BoxConstraints(maxWidth: rect.width, maxHeight: rect.height));
o.flushLayout();
o.flushCompositingBits();
o.flushPaint();
final im = await ro.toImage();
final bd = await im.toByteData(format: ImageByteFormat.png);
final f = File('image.png');
f.writeAsBytesSync(bd.buffer.asUint8List());
print('saved to ${f.absolute}');
}
class OffscreenPainter extends SingleChildRenderObjectWidget {
/// Creates a widget that isolates repaints.
const OffscreenPainter({Key key, Widget child, @required this.size})
: super(key: key, child: child);
final Size size;
@override
RenderOffscreenPainter createRenderObject(BuildContext context) =>
RenderOffscreenPainter(size);
}
class RenderOffscreenPainter extends RenderRepaintBoundary {
RenderOffscreenPainter(this._size);
final Size _size;
@override
void performLayout() {
if (child != null) {
child.layout(BoxConstraints.tight(_size));
size = child.size;
} else {
size = _size;
}
}
}
解决方案
您可以使用转换小部件将小部件推送到屏幕外。根据文档, Transform.translate 在绘制之前移动小部件。
在此示例中,我在底部导航栏添加了一个图标并将其向下移动。它没有显示,但我仍然可以访问 RepaintBoundary。
Transform.translate(
offset: Offset(0,200),
child: RepaintBoundary(
key: iconKey,
child: IconButton(icon: Icon(Icons.star),
onPressed: () {
// Do something
}),
),
),
推荐阅读
- r - 在 R 中为机器学习创建彩色图像数组时出错
- docker - 使用多个具有相同名称的 docker
- ansible - Ansible 如何使用 ssh 隧道管理远程主机?
- annotations - 偏函数作为参数和函数参数注释
- c# - System.EnterpriseServices (v10.0) 的 $(TargetFrameworkVersion) 大于项目 Xamarin 的 $(TargetFrameworkVersion)
- c - 如何修复我的光线投射器中的扭曲透视?
- json - 无需硬编码的 Json Schema 条件检查
- django - 带过滤器的 Django 计数
- entity-framework-core - 实体框架核心导航未更新
- java - java.lang.NullPointerException:无法调用“java.net.URL.toExternalForm()”,因为 org.mapstruct 中的“resource”为空