react-native安卓项目时,遇到了需要将图片放大和长按保存的需求,而react-native-image-zoom-viewer肯定是比较合适的插件,它支持缩放图片、保存图片等常规的图片操作。1、安装
react-native-image-zoom-viewer,用来预览图片、长按保存事件(不能保存,只能长按)
npm install react-native-image-zoom-viewer --save或
yarn add react-native-image-zoom-viewer --save2、安装CameraRoll,保存图片到本地,但是安卓只能保存本地图片
npm install @react-native-community/cameraroll --save或
yarn add @react-native-community/cameraroll --save3、安装react-native-fs,将网络图片下载到本地时会用到
npm install react-native-fs --save或
yarn add react-native-fs --save4、添加权限,进入 项目根目录\android\app\src\main\AndroidManifest.xml,打开,添加下面两行代码:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>注意:
① 如果不添加,保存时会提示:
CameraRoll.saveToCameraRoll(tag,type) is deprecated use the save function
② 安卓6之前添加上面的即可,安卓6之后,需要利用PermissionsAndroid来动态申请权限,
5、引包
import {ScrollView, StyleSheet, ActivityIndicator, Modal, PermissionsAndroid} from 'react-native';
import CameraRoll from "@react-native-community/cameraroll";
import {Text, View, Colors, Button, TouchableOpacity, Image, TextField} from 'react-native-ui-lib';
import ImageViewer from 'react-native-image-zoom-viewer';
import RNFS from 'react-native-fs';
6、定义相关参数
// 控制放大图片的Modal显示隐藏
const [visible, setVisible] = useState(false)
// 设置图片地址
const [zoomImage, setZoomImage] = useState('')
// 点击小图时,设置图片地址和显示Modal
const showBigImg = (url) => {
setZoomImage(url)
setVisible(true)
}
// 保存图片方法
async function savePhoto(url) {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, {
title: "App相册权限申请",
message: "App需要保存图片到您的相册",
buttonNeutral: "稍后询问",
buttonNegative: "取消",
buttonPositive: "确定"
}
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
let androidDownPath = `${RNFS.DocumentDirectoryPath}/${((Math.random() * 1000) | 0)}.jpg`;
let DownloadFileOptions = {
fromUrl: url, //下载路径
toFile: androidDownPath // Local filesystem path to save the file to
}
let result = RNFS.downloadFile(DownloadFileOptions);
result.promise.then(function(val) {
console.log(4555)
console.log("文件下载成功:" + androidDownPath)
let promise = CameraRoll.save(androidDownPath);
promise.then(function(result) {
Toast.show({
type: 'success',
content: '保存成功!'
})
console.log('保存成功!', result)
}).catch(function(error) {
Toast.show({
type: 'error',
content: '保存失败!'
})
console.log('保存失败!\n' + error);
});
}, function(val) {
console.log('Error Result:' + JSON.stringify(val));
}).catch(function(error) {
console.log(error.message);
});
} else {
}
} catch (err) {
console.warn(err)
}
}
7、html代码
<Modal visible={visible} transparent={true}>
<ImageViewer
imageUrls={[{url: zoomImage}]}
menuContext={{ "saveToLocal": "保存图片到相册", "cancel": "取消" }}
enableSwipeDown={true}
onCancel={() => {
setVisible(false);
}}
onClick={() => {
setVisible(false);
}}
onSwipeDown={() => {
setVisible(false);
}}
onSave={(url) => { savePhoto(zoomImage) }}
/>
</Modal>
以上方法在安卓手机测试通过,IOS没做。