向React Native应用添加屏幕捕捉功能

尾火虎
• 阅读 2871
首发于公众号 前端混合开发,欢迎关注。

为用户启用屏幕截图功能已经成为移动应用中用户体验的重要部分。这项功能使用户能够保存或分享应用界面的当前状态,以记住一个难忘的时刻,与朋友分享成就,或向开发者报告问题。

在这篇文章中,我们将探索如何使用 react-native-view-shot 库在React Native应用中实现屏幕捕捉。这个库简化了对特定视图或整个屏幕截图的过程。

在这个教程中,我们将通过实际演示来展示这个库的功能。你可以在GitHub上查看我们简单演示应用的完整代码。

在React Native应用中使用屏幕捕捉的用例

在游戏应用中,提供屏幕截图功能可以让用户在社交媒体上与朋友分享他们的分数、完成的关卡和游戏内的成就。

在报告应用中的错误或问题时,用户可以截取他们的屏幕,以显示他们遇到问题时或由于问题导致的应用当前状态。这可以帮助应用维护者找到或复现问题。

用户还可以在电子商务应用、房地产应用或教育应用中截取诸如产品、房源或讲座幻灯片等内容的屏幕,与他人分享。

为什么使用 react-native-view-shot ?

react-native-view-shot 无疑是实现React Native应用屏幕捕捉功能的最佳维护库。它也高度可定制,因此你可以根据你的需求进行调整。

例如, react-native-record-screen 库记录用户的整个屏幕,而不是捕获特定视图。同时, react-native-screenshot-detect 库检查用户是否使用他们的设备截图,但只适用于用React Native构建的iOS应用。

如果你想要截取某个视图或整个屏幕的快照,我推荐使用 react-native-view-shot 。然而,如果你想要录制整个屏幕,那么请使用 react-native-record-screen

安装 react-native-view-shot

运行以下命令之一:

//npm
$ npm install react-native-view-shot --save

//Yarn
$ yarn add react-native-view-shot

一旦安装完成,你需要构建一次应用。这是因为 react-native-view-shot 向应用添加了新的原生代码。

在构建完成并安装到你的设备上后,你可以开始在你的React Native应用中使用这个库来捕获屏幕或视图。

使用 react-native-view-shot

使用 react-native-view-shot 相当直接了当。我们稍后会进行更详细的演示,但首先,让我们看看这个库是如何工作的。

首先,从React和 react-native-view-shot 库中导入必要的组件:

import ViewShot from 'react-native-view-shot`;
import { useRef, useState } from "react";

接下来,创建一个 viewShot 组件,并将其 useRef 设置为 null 。在此组件内渲染的任何内容都可以作为图像捕获:

然后,我们将创建一个状态来存储捕获的图像的URI:

const [uri, setUri] = useState("");

现在创建一个函数来捕获 viewShot 组件的内容,并将结果URI保存到状态中:

const captureScreen = () => {
    viewShot.current.capture().then((uri) => {
      setUri(uri);
    });
};

最后,我们将使用存储在状态中的 uri 来显示捕获图像的预览:

<View style={styles.previewContainer}>
    <Text>Preview</Text>
    <Image
      source={{ uri: uri }}
      style={styles.previewImage}
      resizeMode="contain"
    />
</View>

react-native-view-shot 的实际演示

既然我们已经看到了 react-native-view-shot 是如何工作的,那么让我们探索一下如何在一个简单的React Native应用中完整地使用它。我们将实现这个库,允许用户在应用中捕获特定的视图,并显示捕获图像的预览:

import {
  Dimensions,
  Image,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import React from 'react';
import ViewShot from 'react-native-view-shot';
import {useRef, useState} from 'react';

const ScreenCapture = () => {
  const viewShot = useRef(null);
  const [uri, setUri] = useState('');

  const captureScreen = () => {
    viewShot.current.capture().then(uri => {
      setUri(uri);
    });
  };

  return (
    <View style={styles.container}>
      <ViewShot ref={viewShot} style={styles.viewShot}>
        <View style={{width: 200, height: 200, backgroundColor: 'red'}} />
      </ViewShot>

      <View style={styles.buttonContainer}>
        <TouchableOpacity onPress={captureScreen} style={styles.btn}>
          <Text style={styles.btnTxt}>CAPTURE</Text>
        </TouchableOpacity>
      </View>

      {uri ? (
        <View style={styles.previewContainer}>
          <Text>Preview</Text>
          <Image
            source={{uri: uri}}
            style={styles.previewImage}
            resizeMode="contain"
          />
        </View>
      ) : null}
    </View>
  );
};
export default ScreenCapture;

const SCREEN_WIDTH = Dimensions.get('screen').width;

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  viewShot: {
    width: SCREEN_WIDTH,
    height: SCREEN_WIDTH,
  },
  buttonContainer: {
    alignSelf: 'stretch',
    justifyContent: 'center',
    alignItems: 'center',
    marginTop: 10,
  },
  btn: {
    padding: 8,
  },
  btnTxt: {
    fontSize: 20,
    fontWeight: 'bold',
  },

  //   previewContainer
  previewContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    marginTop: 10,
    backgroundColor: '#000',
  },
  previewImage: {width: 200, height: 200, backgroundColor: '#fff'},
});

在这个例子中,用户通过在应用内按下一个按钮来触发屏幕截图。以下是应用在 viewShot 被捕获之前的基本状态应该是什么样的:

向React Native应用添加屏幕捕捉功能

捕获的图像将直接在应用程序内显示,而不是保存到设备的相机卷轴中。预览将如下所示:

向React Native应用添加屏幕捕捉功能

如果用户想要重新拍摄图片,他们可以简单地再次按下CAPTURE按钮来替换之前的拍摄。

请记住, react-native-view-shot 不允许应用程序捕获整个屏幕,只能捕获 viewShot 组件内的内容。这意味着捕获视图的大小取决于 viewShot 组件的尺寸 - 在这种情况下,是CAPTURE按钮以上的屏幕部分。

你可以通过编辑 viewShot 组件的 styles 来改变这些尺寸。在这个例子中, viewShot 的宽度和高度是相等的,使我们能够在CAPTURE按钮下显示完整的预览。

当使用 react-native-view-shot 时,捕获的图像会存储在用户设备的临时存储中。你可以利用另一个第三方库,如react-native-camera-roll,让用户将捕获的图像保存到他们设备的相册中。

使用 react-native-view-shot 库的命令式API

react-native-view-shot 也提供了一个更低级别的命令式API,具有更多的可定制性。你可以使用此API设置捕获图像的格式和质量:

captureRef(viewRef, {
  format: "jpg",
  quality: 0.8,
}).then(
  (uri) => console.log("Image can be accessed at: ", uri),
  (error) => console.error("Snapshot failed", error)
);

可用的格式有 pngjpgwebm 。当仅使用 jpg 格式时,你可以将屏幕捕捉质量配置在 0.01.0 之间的值。

排查 react-native-view-shot 问题

虽然 react-native-view-shot 是在React Native应用中获取视图快照的最佳维护选项,但在该库的GitHub仓库中存在多个未解决的问题。有些问题仍在研究中,但让我们来看看下面最常遇到的问题。

当在React Native v0.72.0 中使用 react-native-view-shot 时,尝试截图会导致以下错误:

Failed to capture view snapshot

这个库与React Native的早期版本完全兼容。例如,我们上面演示的示例是在React Native v0.71.8上设置和测试的。

对于v0.72.0,你可以通过将 collapsable 属性设置为 false 来解决这个问题,如下所示:

请注意,这是一个临时的解决方案,可能无法按预期工作。可以通过GitHub上的活跃问题来了解更多信息或检查更近期的更新。

总结

在这篇文章中,我们探讨了如何使用 react-native-view-shot 库在React Native应用中捕获屏幕或特定视图。你可以在GitHub上查看我们简单演示的完整代码。

启用用户捕获和分享应用内容可以增强用户参与度,改善错误报告,并实现各种创新和功能性的使用场景。请务必查阅 react-native-view-shot 库的文档,以获取最新的信息和额外功能。

另外,虽然这个库不需要直接访问用户的相机、麦克风或其他功能,但根据你的使用情况,你可能需要查看我们关于在React Native中管理应用权限的指南。

交流

首发于公众号 大迁世界,欢迎关注。📝 每周一篇实用的前端文章 🛠️ 分享值得关注的开发工具 ❓ 有疑问?我来回答

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

向React Native应用添加屏幕捕捉功能

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Peter20 Peter20
4年前
mysql中like用法
like的通配符有两种%(百分号):代表零个、一个或者多个字符。\(下划线):代表一个数字或者字符。1\.name以"李"开头wherenamelike'李%'2\.name中包含"云",“云”可以在任何位置wherenamelike'%云%'3\.第二个和第三个字符是0的值wheresalarylike'\00%'4\
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
4年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
4年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
暗箭伤人 暗箭伤人
2年前
【www.ithunter.club】 20230922下午
不容易的2023年,我们一起努力【www.ithunter.club】(2023092208:00:00.8872062023092216:00:00.887206)1.人事招聘专员数名(可选远程或入职)2.招聘向坐标东京Yahoo、Shift、L
Python进阶者 Python进阶者
2年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这