I am currently working on react-native photo sharing app for Android. Used native share method but it only share message and title. No options to share an image.
Looking after so many questions here couldn't find any straight forward way.
Please provide help.
This is the message I am getting Share awesome status on whatsapp using Khela #imageurl. Download #urltoplaystore
To share any image in React Native you are right you need to use the Share from react-native library itself, and you were wondering what is needed for an image, the answer it's really simple, you just need to use a Base64 image.
Check it out a working snack: snack.expo.io/#abrahamcalf/share-image
Wrap the code:
import * as React from 'react';
import {
Text,
View,
StyleSheet,
Image,
Share,
TouchableOpacity,
} from 'react-native';
export default class App extends React.Component {
state = {
cat: 'data:image/jpeg;base64,some-encoded-stuff;
};
handleSharePress = () => {
Share.share({
title: 'Share',
message: 'My amazing cat 😻',
url: this.state.cat,
});
};
render() {
return (
<View style={styles.container}>
<Image source={{ uri: this.state.cat }} style={styles.img} />
<TouchableOpacity onPress={this.handleSharePress}>
<Text>Share Image</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'space-around',
alignItems: 'center',
},
img: {
width: 200,
height: 300,
},
});
If you want to try something else, probably complex, I recommend to check out the react-native-share library from the React Native Community.
import Icon from 'react-native-vector-icons/Feather';
import Share from 'react-native-share';
import RNFetchBlob from 'rn-fetch-blob';
import React, {Component} from 'react';
const fs = RNFetchBlob.fs;
class ProductDetail extends Component {
constructor(props) {
super(props);
this.state = {};
}
shareTheProductDetails(imagesPath) {
let {productDetails} = this.state;
let imagePath = null;
RNFetchBlob.config({
fileCache: true,
})
.fetch('GET', imagesPath.image)
// the image is now dowloaded to device's storage
.then((resp) => {
// the image path you can use it directly with Image component
imagePath = resp.path();
return resp.readFile('base64');
})
.then((base64Data) => {
// here's base64 encoded image
var imageUrl = 'data:image/png;base64,' + base64Data;
let shareImage = {
title: productDetails.product_name, //string
message:
'Description ' +
productDetails.product_description +
' http://beparr.com/', //string
url: imageUrl,
// urls: [imageUrl, imageUrl], // eg.'http://img.gemejo.com/product/8c/099/cf53b3a6008136ef0882197d5f5.jpg',
};
Share.open(shareImage)
.then((res) => {
console.log(res);
})
.catch((err) => {
err && console.log(err);
});
// remove the file from storage
return fs.unlink(imagePath);
});
}
render() {
return (
<TouchableOpacity
style={{
borderWidth: 0,
left:(5),
top:(2),
}}
onPress={() =>
this.shareTheProductDetails(images)
}>
<Icon
style={{
left: moderateScale(10),
}}
name="share-2"
color={colors.colorBlack}
size={(20)}
/>
</TouchableOpacity>
)}
}
Related
Hello I'm working with my project and I want to fetch poster_patch into variable to print every single image of miniatures in my app. Im working with react-native in. Here is some code of my app. I want to create function to fetch value of path_poster and add it after to uri
Top.js
`
import React,{useState,useEffect} from "react";
import { View, StyleSheet, Text } from "react-native";
import MovieBox from './MovieBox';
const API_URL="https://api.themoviedb.org/3/movie/top_rated?api_key=xxx"
export default function Top(){
const [movies,setMovies]=useState([]);
useEffect(()=>{
fetch(API_URL)
.then((res)=>res.json())
.then(data =>{
console.log(data);
setMovies(data.results);
})
}, [])
return (
movies.map((movieReq)=><MovieBox key ={movieReq.id} {...movieReq}/>)
);
};
`
MovieBox.js
`
import React from 'react';
import { View, StyleSheet, Text,Image } from "react-native";
const API_IMG = "https://image.tmdb.org/t/p/w500";
function MovieBox ({title, poster_patch,vote_average,release_date,overview}){
const styles = StyleSheet.create({
container: {
paddingTop: 50,
},
tinyLogo: {
width: 50,
height: 50,
},
logo: {
width: 66,
height: 58,
},
});
return(
<View>
<Text>
{title} rated:
{vote_average}
</Text>
<Image source={{
uri: API_IMG + HERE I WANT TO ADD VARIABLE TO POSTER_PATCH,
}}
style={styles.tinyLogo}
/>
</View>
)
}
export default MovieBox;
`
How to get values from poster_path and add it into uri
Join base url and path for example using concat.
<Image source={{
uri: API_IMG.concat(poster_path),
}}
style={styles.tinyLogo}
/>
See Images for details.
I copied fallowing code from a github project and tried using expo. The project executed without error but when i press button nothing happens. not even error this is my code
NB- I stetted an alert inside onChooseImagePress and alert is working fine
import React from 'react';
import { Image, StyleSheet, Button, Text, View, Alert, } from 'react-native';
import { ImagePicker } from 'expo';
import * as firebase from 'firebase';
import {firebaseConfig} from "./ApiKeys";
export default class HomeScreen extends React.Component {
static navigationOptions = {
header: null,
};
onChooseImagePress = async () => {
let result = await ImagePicker.launchCameraAsync();
//let result = await ImagePicker.launchImageLibraryAsync();
if (!result.cancelled) {
this.uploadImage(result.uri, "test-image")
.then(() => {
Alert.alert("Success");
})
.catch((error) => {
Alert.alert(error);
});
}
}
uploadImage = async (uri, imageName) => {
const response = await fetch(uri);
const blob = await response.blob();
var ref = firebase.storage().ref().child("images/" + imageName);
return ref.put(blob);
}
render() {
return (
<View style={styles.container}>
<Button title="Choose image..." onPress={this.onChooseImagePress} />
</View>
);
}
}
const styles = StyleSheet.create({
container: { flex: 1, paddingTop: 50, alignItems: "center", },
});
}
Multiple syntactical issues in your code:
const styles... should be defined inside the render function currently its dangling outside the class
Brackets mismatch
return (
<View style={styles.container}>
<Button title="Choose image..." onPress={this.onChooseImagePress} />
</View>
);
}
} // the class ends here
Please let me know if it still doesn't work
Try to use below code
constructor() {
super();
this.state = { };
this.onChooseImagePress= this.onChooseImagePress.bind(this);
}
<Button title="Choose image..." onPress={() => this.onChooseImagePress()} />
I have requirement where i need to get a random image every time when i click an button. I don't want picker to come up for the camera-roll with images, instead random image should selected from the camera folder and display in the image view.
I have followed the official FB tutorial of camera roll. Please find the code as below
_handleButtonPress = () => {
CameraRoll.getPhotos({
first: 20,
assetType: 'Photos',
})
.then(r => {
this.setState({ photos: r.edges });
})
.catch((err) => {
});
};
But this code will select the recently clicked images and display in the picker. Instead of to randomly select the uri of the image and display in the imageview. Any help is appreciated.
Regards,
Sharath
You essentially have the photos and all the necessary metadata once you set the state: this.setState({ photos: r.edges })
All you have to do is pick a random image from there. Here's how I did it:
import React, { Component } from 'react';
import {
StyleSheet,
View,
Image,
CameraRoll,
Button
} from 'react-native';
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
img: null
}
}
getRandomImage = () => {
const fetchParams = {
first: 25,
}
CameraRoll.getPhotos(fetchParams)
.then(data => {
const assets = data.edges
const images = assets.map((asset) => asset.node.image)
const random = Math.floor(Math.random() * images.length)
this.setState({
img: images[random]
})
})
.catch(err => console.log)
}
render() {
return (
<View style={styles.container}>
{ this.state.img ?
<Image
style={styles.image}
source={{ uri: this.state.img.uri }}
/>
: null
}
<Button title="Get Random Image from CameraRoll" onPress={this.getRandomImage}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
image: {
width: '100%',
height: '75%',
margin: 10,
}
});
I am facing a problem with retrieving current URL from WebView. Currently, I am using the following method get the URL
onNavigationStateChange()
Recently noticed that URL is deprecated! I need to use source prop to get the URL. But I couldn't figure it out. Also, the function above gets called twice. Is there any way to get URL in loadingFinished() function?
Source: https://facebook.github.io/react-native/docs/webview.html
Thanks
You can take use of onNavigationStateChange. On Navigation state change, update state. And use url from state whenever required.
Code:-
import React, { Component } from 'react';
import { Text, View, WebView } from 'react-native';
const initialUrl = 'https://github.com';
let url = '';
export default class App extends Component {
state = {
url: initialUrl,
};
onNavigationStateChange = navState => {
if (url!==navState.url) {
url = navState.url;
alert(url);
this.setState({
url: url
})
}
};
render() {
const { url } = this.state;
return (
<View style={{paddingTop: 24, flex: 1}}>
<Text style={{backgroundColor: 'black', color: 'white'}}>{ url }</Text>
<WebView
style={{ flex: 1}}
source={{
uri: initialUrl,
}}
onNavigationStateChange={this.onNavigationStateChange}
startInLoadingState
scalesPageToFit
javaScriptEnabled
/>
</View>
);
}
}
Live example on snack https://snack.expo.io/SyRNRLj-G
I am new in react-native and i want to open url in default browser like Chrome in Android and iPhone both.
We open url via intent in Android same like functionality i want to achieve.
I have search many times but it will give me the result of Deepklinking.
You should use Linking.
Example from the docs:
class OpenURLButton extends React.Component {
static propTypes = { url: React.PropTypes.string };
handleClick = () => {
Linking.canOpenURL(this.props.url).then(supported => {
if (supported) {
Linking.openURL(this.props.url);
} else {
console.log("Don't know how to open URI: " + this.props.url);
}
});
};
render() {
return (
<TouchableOpacity onPress={this.handleClick}>
{" "}
<View style={styles.button}>
{" "}<Text style={styles.text}>Open {this.props.url}</Text>{" "}
</View>
{" "}
</TouchableOpacity>
);
}
}
Here's an example you can try on Expo Snack:
import React, { Component } from 'react';
import { View, StyleSheet, Button, Linking } from 'react-native';
import { Constants } from 'expo';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Button title="Click me" onPress={ ()=>{ Linking.openURL('https://google.com')}} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
},
});
A simpler way which eliminates checking if the app can open the url.
loadInBrowser = () => {
Linking.openURL(this.state.url).catch(err => console.error("Couldn't load page", err));
};
Calling it with a button.
<Button title="Open in Browser" onPress={this.loadInBrowser} />
Try this:
import React, { useCallback } from "react";
import { Linking } from "react-native";
OpenWEB = () => {
Linking.openURL(url);
};
const App = () => {
return <View onPress={() => OpenWeb}>OPEN YOUR WEB</View>;
};
Hope this will solve your problem.
In React 16.8+, the following can be used to create an ExternalLinkBtn component for opening external links in the browser.
import React from 'react';
import { Button, Linking } from 'react-native';
const ExternalLinkBtn = (props) => {
return <Button
title={props.title}
onPress={() => {
Linking.openURL(props.url)
.catch(err => {
console.error("Failed opening page because: ", err)
alert('Failed to open page')
})}}
/>
}
Below is an example of using our ExternalLinkBtn component
export default function exampleUse() {
return (
<View>
<ExternalLinkBtn title="Example Link" url="https://example.com" />
</View>
)
}