向React Native應用新增螢幕捕捉功能

發表於2024-02-27
首發於公眾號 前端混合開發,歡迎關注。

為使用者啟用螢幕截圖功能已經成為移動應用中使用者體驗的重要部分。這項功能使使用者能夠儲存或分享應用介面的當前狀態,以記住一個難忘的時刻,與朋友分享成就,或向開發者報告問題。

在這篇文章中,我們將探索如何使用 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 被捕獲之前的基本狀態應該是什麼樣的:

image.png

捕獲的影像將直接在應用程式內顯示,而不是儲存到裝置的相機卷軸中。預覽將如下所示:

image.png

如果使用者想要重新拍攝圖片,他們可以簡單地再次按下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 已收錄,有一線大廠面試完整考點、資料以及我的系列文章。

相關文章