Flutter屏幕截图插件screenshot_ntv的使用

发布于 1周前 作者 ionicwang 来自 Flutter

Flutter屏幕截图插件screenshot_ntv的使用

插件介绍

screenshot_ntv 是一个用于在Android和iOS平台上通过原生代码获取屏幕截图的Flutter插件。 它解决了 RepaintBoundary 无法截取平台视图的问题。

使用方法

dependencies:
  screenshot_ntv: ^1.0.2

截取屏幕截图示例代码

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'package:screenshot_ntv/screenshot_ntv.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Screenshot_ntv Demo',
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  const Home({super.key});

  [@override](/user/override)
  State<StatefulWidget> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final imagesList = <Uint8List>[];

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Plugin example app'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          final result = await ScreenshotNtv.takeScreenshot();
          if (result != null) {
            imageList.add(result);
            setState(() {});
          }
        },
        child: const Icon(Icons.screenshot),
      ),
      body: imageList.isEmpty
          ? const Center(child: Text("not screenshot"))
          : SingleChildScrollView(
              padding: const EdgeInsets.all(1 ),
              child: Center(
                child: Wrap(
                  spacing: 1,
                  runSpacing: 1,
                  children: List.generate(
                    imageList.length,
                    (index) => GestureDetector(
                      onTap: () {
                        showDialog(
                          context: context,
                          builder: (_) => ScreenshotView(
                            data: imageList[index],
                          ),
                        );
                      },
                      child: Container(
                        decoration: BoxDecoration(
                          boxShadow: [
                            BoxShadow(
                                blurRadius: 15,
                                color: Colors.black.withOpacity(0.15))
                          ],
                        ),
                        child: Image.memory(
                          imageList[index],
                          height: 250,
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            ),
    );
  }
}

class ScreenshotView extends StatelessWidget {
  const ScreenshotView({
    super.key,
    required this.data,
  });

  final Uint8List data;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        Navigator.pop(context);
      },
      child: Container(
        margin: const EdgeInsets.all(20),
        child: Image.memory(data),
      ),
    );
  }
}

更多关于Flutter屏幕截图插件screenshot_ntv的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter屏幕截图插件screenshot_ntv的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用screenshot_ntv插件来实现屏幕截图的示例代码。这个插件允许你捕获当前屏幕的内容,并将其保存为图像文件或作为图像数据使用。

首先,你需要在你的pubspec.yaml文件中添加screenshot_ntv依赖项:

dependencies:
  flutter:
    sdk: flutter
  screenshot_ntv: ^x.y.z  # 请替换为最新版本号

然后,运行flutter pub get来安装依赖项。

接下来,你可以在你的Flutter应用中使用ScreenshotController来捕获屏幕截图。以下是一个完整的示例,展示了如何捕获屏幕截图并将其保存到设备的存储中:

import 'package:flutter/material.dart';
import 'package:screenshot_ntv/screenshot_controller.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Screenshot Example'),
        ),
        body: ScreenshotExample(),
      ),
    );
  }
}

class ScreenshotExample extends StatefulWidget {
  @override
  _ScreenshotExampleState createState() => _ScreenshotExampleState();
}

class _ScreenshotExampleState extends State<ScreenshotExample> with WidgetsBindingObserver {
  late final ScreenshotController screenshotController = ScreenshotController();

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance?.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance?.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      // 可以在这里处理从后台恢复时的逻辑,如果需要的话
    }
  }

  Future<void> _capturePng() async {
    try {
      final File imageFile = await screenshotController.capturePng();
      print("PNG Screenshot saved at ${imageFile.path}");

      // 如果需要,可以在这里显示一个Snackbar或进行其他UI更新
      // ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Screenshot saved")));

      // 示例:将截图路径复制到剪贴板(可选)
      await Clipboard.setData(ClipboardData(text: imageFile.path));
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("Screenshot path copied to clipboard")));
    } catch (e) {
      print("Failed to capture screenshot: $e");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text('Tap the button to capture a screenshot'),
          SizedBox(height: 20),
          ElevatedButton(
            onPressed: _capturePng,
            child: Text('Capture Screenshot'),
          ),
          SizedBox(height: 20),
          Text('Make sure to wrap your widget tree with Screenshot widget using ScreenshotController'),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    // 注意:这里需要将整个需要截图的widget树包裹在Screenshot组件中
    return Screenshot(
      controller: screenshotController,
      child: Scaffold(
        appBar: AppBar(
          title: Text('Screenshot Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('Tap the button to capture a screenshot'),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: _capturePng,
                child: Text('Capture Screenshot'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

注意

  1. 在上面的代码中,Screenshot组件应该包裹你需要截图的整个widget树。为了简化示例,我将Screenshot组件直接放在了_ScreenshotExampleStatebuild方法中,并注释掉了原来的body内容。但在实际应用中,你可能需要调整Screenshot的位置,以确保它包裹了正确的widget树。
  2. _capturePng方法用于捕获屏幕截图,并将结果保存为一个PNG文件。然后,它打印文件路径到控制台,并可以选择性地显示一个Snackbar或将文件路径复制到剪贴板。
  3. 你需要确保在AndroidManifest.xmlInfo.plist(对于iOS)中添加了必要的权限,以便应用能够写入存储。

希望这个示例对你有帮助!如果你有任何其他问题,请随时提问。

回到顶部