首页 > 解决方案 > 截屏隐藏 Flutter 中的一些小部件

问题描述

我想截取屏幕截图,但我想在生成的截图中隐藏/模糊/绘制一些小部件,而不是在应用程序中。像这样的东西:

我们在应用程序中看到的 我想在屏幕截图中得到什么

第一张图片是我想在应用程序中看到的,没有变化。第二张图片是我想在屏幕截图中看到的,绘制了一个特定的小部件。

我的第一个想法是计算特定小部件的绝对坐标,但为了做到这一点,我应该为屏幕的每个小部件添加一个 GlobalKey,这对于我的情况是不可行的。

如何在不向屏幕的每个小部件添加 GlobalKey的情况下执行此操作?

我目前截取屏幕截图的方法是:

final pixelRatio = MediaQuery.of(context).devicePixelRatio;
final boundary = boundaryKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
final image = await boundary.toImage(pixelRatio: pixelRatio);

这就是我用来获取具有 GlobalKey 的 Widget 坐标的方法:

extension GlobalKeyExtension on GlobalKey {
  Rect? get globalPaintBounds {
    final renderObject = currentContext?.findRenderObject();
    var translation = renderObject?.getTransformTo(null).getTranslation();
    if (translation != null) {
      return renderObject!.paintBounds
          .shift(Offset(translation.x, translation.y));
    } else {
      return null;
    }
  }
}

标签: flutterdart

解决方案


屏幕截图小部件是您正在寻找的。

在您的 pubspec.yaml 文件中,在依赖项下添加以下行

dependencies:
  screenshot: ^0.3.0

然后你可以像这样使用它。我只是添加了一些按钮和容器来展示它。您可以根据需要对其进行自定义。基本上这样做是当您将小部件作为具有控制器的屏幕截图小部件的子级时,您可以将其捕获为图像。

import 'dart:math';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:screenshot/screenshot.dart';

class ScreenCapture extends StatefulWidget {
  ScreenCapture({Key key}) : super(key: key);

  @override
  _ScreenCaptureState createState() => _ScreenCaptureState();
}

class _ScreenCaptureState extends State<ScreenCapture> {
  Uint8List _imageFile;
  Color captureColor = Colors.red, inAppColor = Colors.green, inAppImageBG;
  String capturingText = "Capturing State";
  String inAppDisplayText = "In App Display";
  String inAppText;
  ScreenshotController screenshotController = new ScreenshotController();

  @override
  void initState() {
    super.initState();
    inAppImageBG = inAppColor;
    inAppText = inAppDisplayText;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [capturedImageContainer(), inAppImage(), capture()],
      ),
    );
  }

  Widget capturedImageContainer() {
    return _imageFile != null
        ? Container(
            color: Colors.black,
            height: 100,
            width: 300,
            child: Image.memory(_imageFile),
          )
        : Container(color: Colors.black, height: 100, width: 300);
  }

  Widget inAppImage() {
    return Screenshot(
      controller: screenshotController,
      child: Container(
        color: inAppImageBG,
        height: 100,
        width: 300,
        child: Text(inAppText),
        alignment: Alignment.center,
      ),
    );
  }

  Widget capture() {
    return GestureDetector(
      onTap: () {
        doCapture();
      },
      child: Container(
        height: 100,
        width: 300,
        color: Colors.amber,
        child: Text("Capture"),
        alignment: Alignment.center,
      ),
    );
  }

  doCapture() async {
    Future.delayed(const Duration(milliseconds: 500), () {
      setState(() {
        inAppImageBG = captureColor;
        inAppText = capturingText + Random().nextInt(10).toString();
        Future.delayed(const Duration(milliseconds: 10), () {
          screenshotController
              .capture(delay: Duration(milliseconds: 1))
              .then((Uint8List image) async {
            setState(() {
              _imageFile = image;
              Future.delayed(const Duration(milliseconds: 1500), () {
                setState(() {
                  inAppImageBG = inAppColor;
                  inAppText = inAppDisplayText;
                });
              });
            });
          }).catchError((onError) {
            print(onError);
          });
        });
      });
    });
  }
}

推荐阅读