react-native-image-viewer
react-native-image-viewer copied to clipboard
'Save image to album' not working
Hi, I'm testing my app on an Android device, and the functionality of saving the image to the phone's album is not working (after long-pressing the image). Is anyone else running into the same issue? In any case, is there a way of disabling the menu after long-pressing? I'm using Expo to develop the app
I am experiencing the same on IOS
This works just fine on iOS and Android.
The onSave
prop won't automatically save the image. You'll have to import CameraRoll
from react-native-community
and save the image that way. Read over the following to import it correctly: https://github.com/react-native-community/react-native-cameraroll
Here's an example of how i'm using it in my app:
import React from "react";
import { ActivityIndicator, Modal, Alert } from "react-native";
import CameraRoll from "@react-native-community/cameraroll";
import ImageViewer from "react-native-image-zoom-viewer";
export default class Example extends React.Component {
state = {
image_index: 0,
images: [],
show_modal: false
};
constructor(props) {
super(props);
this._getImages();
}
_getImages = () => {
// Make some external request to get images if needed... This is just an example
let images = [
{
uri: "some uri",
props: {
id: 1
},
},
{
uri: "some uri2",
props: {
id: 2
},
}
];
this.setState({ images });
};
_saveImage = uri => {
let promise = CameraRoll.saveToCameraRoll(uri);
promise
.then(function(result) {
Alert.alert(
"Success",
"Image Saved to Photo Gallery",
[
{
text: "OK"
}
],
{ cancelable: false }
);
})
.catch(function(error) {
Alert.alert(
"Error Saving Image",
error,
[
{
text: "OK"
}
],
{ cancelable: false }
);
});
};
render() {
return (
<Modal visible={this.state.show_modal} transparent={true}>
<ImageViewer
imageUrls={this.state.images}
index={this.state.image_index}
enableSwipeDown
enablePreload
loadingRender={() => (
<ActivityIndicator
style={{
justifyContent: "center",
alignSelf: "center"
}}
size="large"
color="#FFFFFF"
/>
)}
onSave={uri => this._saveImage(uri)}
onSwipeDown={() => this.setState({ show_modal: false })}
menuContext={{
saveToLocal: "Save Image",
cancel: "Cancel"
}}
/>
</Modal>
);
}
}
const saveImage = async uri => {
RNFetchBlob.config({
fileCache: true,
appendExt: 'png',
})
.fetch('GET', uri)
.then(res => {
CameraRoll.saveToCameraRoll(res.data, 'photo')
.then(res =>
Alert.alert(
'Success',
'Image Saved to Photo Gallery',
[
{
text: 'OK',
},
],
{cancelable: false},
),
)
.catch(err =>
Alert.alert(
'Error Saving Image',
error,
[
{
text: 'OK',
},
],
{cancelable: false},
),
);
})
.catch(error =>
Alert.alert(
'Error Saving Image',
error,
[
{
text: 'OK',
},
],
{cancelable: false},
),
);
};
<ImageViewer
ref={n => {
imageViewer = n;
}}
enablePreload={true}
useNativeDriver={true}
onSave={uri => saveImage(uri)}
imageUrls={images}
/>
onSave will let you write custom code for image store operation. For the image store operation you can use rn-fetch-blob like what I did.
因为 saveToLocal 方法中
if (!this.props.onSave) { CameraRoll.saveToCameraRoll(this.props.imageUrls[this.state.currentShowIndex || 0].url); this!.props!.onSaveToCamera!(this.state.currentShowIndex); } else { this.props.onSave(this.props.imageUrls[this.state.currentShowIndex || 0].url); }
!this.props.onSave有默认值所以此条件永远不满足,导致保存失败。临时解决方案 onSave值设置null 可以正常运行