Flutterdart将部分OFFSCREEN小部件捕获为图像[重复]

Flutterdart将部分OFFSCREEN小部件捕获为图像[重复],第1张

Flutter / dart将部分OFFSCREEN小部件捕获为图像[重复]

这让我很好奇是否可行,因此我做了一个快速的模型来证明它确实有效。但是请注意,这样做实际上是在故意破坏flutter进行优化的工作,因此您实际上不应在绝对必要的地方使用它。

无论如何,这是代码:

import 'dart:math';import 'dart:ui' as ui;import 'package:flutter/material.dart';import 'package:flutter/rendering.dart';void main() => runApp(MyApp());class UiImagePainter extends CustomPainter {  final ui.Image image;  UiImagePainter(this.image);  @override  void paint(ui.Canvas canvas, ui.Size size) {    // simple aspect fit for the image    var hr = size.height / image.height;    var wr = size.width / image.width;    double ratio;    double translateX;    double translateY;    if (hr < wr) {      ratio = hr;      translateX = (size.width - (ratio * image.width)) / 2;      translateY = 0.0;    } else {      ratio = wr;      translateX = 0.0;      translateY = (size.height - (ratio * image.height)) / 2;    }    canvas.translate(translateX, translateY);    canvas.scale(ratio, ratio);    canvas.drawImage(image, new Offset(0.0, 0.0), new Paint());  }  @override  bool shouldRepaint(UiImagePainter other) {    return other.image != image;  }}class UiImageDrawer extends StatelessWidget {  final ui.Image image;  const UiImageDrawer({Key key, this.image}) : super(key: key);  @override  Widget build(BuildContext context) {    return CustomPaint(      size: Size.infinite,      painter: UiImagePainter(image),    );  }}class MyApp extends StatefulWidget {  @override  _MyAppState createState() => _MyAppState();}class _MyAppState extends State<MyApp> {  GlobalKey<OverRepaintBoundaryState> globalKey = GlobalKey();  ui.Image image;  @override  Widget build(BuildContext context) {    return MaterialApp(      home: Scaffold(        appBar: AppBar(),        body: image == null ? Capturer(     overRepaintKey: globalKey,   ) : UiImageDrawer(image: image),        floatingActionButton: image == null ? FloatingActionButton(     child: Icon(Icons.camera),     onPressed: () async {       var renderObject = globalKey.currentContext.findRenderObject();       RenderRepaintBoundary boundary = renderObject;       ui.Image captureImage = await boundary.toImage();       setState(() => image = captureImage);     },   ) : FloatingActionButton(     onPressed: () => setState(() => image = null),     child: Icon(Icons.remove),   ),      ),    );  }}class Capturer extends StatelessWidget {  static final Random random = Random();  final GlobalKey<OverRepaintBoundaryState> overRepaintKey;  const Capturer({Key key, this.overRepaintKey}) : super(key: key);  @override  Widget build(BuildContext context) {    return SingleChildScrollView(      child: OverRepaintBoundary(        key: overRepaintKey,        child: RepaintBoundary(          child: Column( children: List.generate(   30,   (i) => Container(         color: Color.fromRGBO(random.nextInt(256), random.nextInt(256), random.nextInt(256), 1.0),         height: 100,       ), ),          ),        ),      ),    );  }}class OverRepaintBoundary extends StatefulWidget {  final Widget child;  const OverRepaintBoundary({Key key, this.child}) : super(key: key);  @override  OverRepaintBoundaryState createState() => OverRepaintBoundaryState();}class OverRepaintBoundaryState extends State<OverRepaintBoundary> {  @override  Widget build(BuildContext context) {    return widget.child;  }}

它正在做的是一个滚动视图,其中封装了列表(列),并确保repaintBoundary在列周围。对于使用列表的代码,它根本无法捕获所有子项,因为列表本质上是repaintBoundary本身。

特别注意’overRepaintKey’和OverRepaintBoundary。通过遍历渲染子代,您可能可以不使用它而逃脱,但这使它变得容易得多。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4909612.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-12
下一篇 2022-11-12

发表评论

登录后才能评论

评论列表(0条)

保存