关于flutter:开发经验Flutter中对CustomScrollViewSliver组件截长图

问题

分享以后页面的需要,有时须要对页面进行截图。Flutter中截图个别应用RepaintBoundary搭配GlobalKey获取Widget的截图(PlatformView 无奈截图)。

然而当须要截图的指标是CustomScrollView时,尤其是应用了SliverPersistentHeaderSliver组件时,不容易想出RepaintBoundary的嵌套地位,也就无奈获取长截图。

计划

百度根本查不到有用的信息,甚至还有一些离奇的计划:

下面长截图的现实状况是 SingleChildScrollView 这种容许咱们在 child 套一层 RepaintBoundary,但理论中也可能是 CustomScrollView 这种严格限度 children 类型的,此时咱们可能就须要借助相似 SliverToBoxAdapter 这种容器,并且在每个 child 上都套一个 RepaintBoundary

在每个 child 上都套一个 RepaintBoundary 显然是十分十分蹩脚的计划,在拍脑袋之前,咱们尽可能的多检索一些材料:

https://github.com/SachinGanesh/screenshot/issues/10#issuecomment-586302204

原文:

In your ListView that you wanna take a full screenshot, put a NeverScrollableScrollPhysics on it, then what is going to take control of the scrolling is the SingleChildScrollView.

意思就是给你的CustomScrollView一个NeverScrollableScrollPhysics,而后扔到SingleChildScrollView中进行截图。

很显然这个计划是更适合的,因为不须要关怀每一个child,因为child的数量可能尤其的多,难以去追踪CustomScrollView的每一个child

解决

组件:

GlobalKey paintKey = GlobalKey();
// 是否处在打印模式
bool printMode = false;

@override
Widget build(BuildContext context) {
// 页面
Widget body = CustomScrollView(
    physics: printMode ? NeverScrollableScrollPhysics() : null,
);
// 截图中
if (printMode) {
    body = AbsorbPointer(
        child: SingleChildScrollView(
        child: RepaintBoundary(
            key: paintKey,
            child: Container(
            color: ColorPlate.lightGray,
            child: body,
            ),
        ),
        ),
    ),
}
return body;
}

截图办法:

_share() async {
    setState(() {
      printMode = true;
    });
    await Future.delayed(Duration(milliseconds: 50));
    RenderRepaintBoundary boundary =
        paintKey.currentContext!.findRenderObject() as RenderRepaintBoundary;

    ui.Image image = await boundary.toImage(pixelRatio: 3);

    ByteData byteData = (await image.toByteData(
      format: ui.ImageByteFormat.png,
    ))!;
    Uint8List pngBytes = byteData.buffer.asUint8List();

    print('截图胜利 ${pngBytes}')

    setState(() {
      printMode = false;
    });
  }

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理