Is this inline block+text layout possible at all in React Native? - html

I'm trying to achieve the following layout in React Native (layout created successfully on web in HTML+CSS):
The tricky part is the gray breadcrumb element that should inline with the description. My code for the breadcrumb+description part is as follows:
<Text style={styles.description}>
<Text style={styles.quantity}>{quantity}</Text>
{description}
</Text>
styles.ts:
description: {
fontSize: 14,
fontFamily: 'light',
flexDirection: 'row',
flexWrap: 'wrap',
},
quantity: {
fontSize: 13,
color: Color.white,
backgroundColor: Color.placeholder,
borderRadius: 16,
paddingHorizontal: 400,
},
It results in this:
As you can see, the borderRadius and padding properties get ignored on the quantity element.
I have also tried doing it with View elements instead of Text ones but the description simply goes fully to the next line when it overflows (classic block behaviour).
So, is there any trick/workaround to achieving this layout in RN? Thanks.

Wrap the nested text in a view with a flex direction of row, and then go about wrapping the text component in a view (demo):
import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';
import { Text } from 'react-native-paper';
const Color = {
white: 'white',
placeholder: 'blue',
};
const quantity = 50;
const description =
'Once upon a time there was a story told that took a very long time to tell.';
const InlineText = ({ style, children, ...props }) => {
style = StyleSheet.flatten(style)
const textStyle = {
...style,
// // remove styles that dont work on android/ios
paddingHorizontal:null,
marginHorizontal:null,
borderRadius:null
}
return (
<View style={[{alignItems:'center',justifyContent:'center'},style]}>
<Text {...props} style={textStyle}>{children}</Text>
</View>
);
};
export default function App() {
return (
<View style={styles.container}>
<View style={{ flexDirection: 'row' }}>
<Text style={styles.description}>
{/*InlineText no longer inherits the parent text styles*/}
<InlineText style={[styles.description,styles.quantity]}>{quantity}</InlineText>
{description}
</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
description: {
fontSize: 14,
fontFamily: 'light',
flexDirection: 'row',
flexWrap: 'wrap',
},
quantity: {
fontSize: 13,
color: Color.white,
backgroundColor: Color.placeholder,
borderRadius: 16,
paddingHorizontal: 5,
marginHorizontal: 3,
},
});

Related

React-PDF stripping style from nested components output by render callback

I am attempting to pass a shared component to a <View fixed> element, however it appears that the output has missing style properties...
It appears that the child component's styling is preserved, but any grandchildren do not...
Further investigation shows that even hardcoding all of the <View>, <Text> and style also results in nested elements being stripped...
React-PDF Repl
Is there any reason why this is happening? Is there a way in which I can get the styles included?
const TableHeaders = () => (
<TableRow>
{['name', 'age', 'location'].map(label =>
<TableCell>{label}</TableCell>)}
</TableRow>
);
const TableRow = ({children}) => <View style={styles.row}>{children}</View>;
const TableCell = ({children}) => (
<View style={styles.column}>
<Text>{children}</Text>
</View>
);
const FixedHeader = () => <View fixed render={() => <TableHeaders />} />;
const HardcodedHeader = () => (
<View render={() => (
<View style={styles.row}>
{['name', 'age', 'location'].map(label => (
<View style={styles.column}>
<Text>{label}</Text>
</View>
))}
</View>
)} />
)
const HardcodedHeaderWithHardcodedStyles = () => (
<View render={() => (
<View style={{
flexDirection: 'row',
backgroundColor: 'lightblue',
borderRadius: 4,
margin: '2px 0',
padding: '10px 7px'
}}>
{['name', 'age', 'location'].map(label => (
<View style={{
margin: '0 5px',
fontSize: 10,
color: 'red'
}}>
<Text>{label}</Text>
</View>
))}
</View>
)} />
)
const Quixote = () => (
<Document>
<Page style={styles.body}>
<TableHeaders />
<FixedHeader />
<HardcodedHeader />
<HardcodedHeaderWithHardcodedStyles />
</Page>
</Document>
);
const styles = StyleSheet.create({
column: {
margin: '0 5px',
fontSize: 10,
color: 'red'
},
row: {
flexDirection: 'row',
backgroundColor: 'lightblue',
borderRadius: 4,
margin: '2px 0',
padding: '10px 7px'
},
body: {
paddingTop: 35,
paddingBottom: 65,
paddingHorizontal: 35,
}
});
ReactPDF.render(<Quixote />);
SOLVED!
It turns out that yes, using the render={() => {}} prop to render elements with children does cause some headaches if you're not careful.
Margin and Padding
For Margin and Padding I was originally defining the values using a string format mirroring how we would do it within a proper css file:
{
[margin|padding]: '[vertical]px [horizontal]px'
}
This must somehow get garbled by the render process and is misunderstood. After a lot of experimenting, it turns out that if we split out the definitions into their compoent parts and pass number values rather than strings, it's actually carried through properly (note: Numbers are interpreted as 'px' unless otherwise configged):
{
marginTop: 2,
marginBottom: 2,
paddingTop: 10,
paddingBottom: 10,
paddingLeft: 7,
paddingRight: 7
}
Fonts
Fonts are a little more strange. It seems that the render callback method somehow strips the association of fontFamily, fontSize, fontWeight etc from any child element from its parent. This means that we have to either redefine these parts in the <Text> element we want to style, or we can move the original definitions down to those <Text> elements from their <View> containers.
Persisting issues
The only thing that I couldn't get to work was the borderRadius.
See the new, updated Repl

"temporary" variant not showing in Drawer component Material-ui

I am trying to make the drawer component on material-ui a responsive drawer, by making it to be toggled open and close on smaller screens and permanent on desktop
I followed the documentation on mui, which says to add the temporary variant to the drawer, however it doesn't show up at all on desktop mode
Below is my drawer component
import React from "react";
import ReactDOM from "react-dom";
import { useHistory } from "react-router-dom";
import { makeStyles, Typography, Drawer, Toolbar, Divider, List, ListItem, ListItemText, ListItemIcon, Container, Box } from "#material-ui/core";
import HomeOutlinedIcon from '#material-ui/icons/HomeOutlined';
import AlternateEmailOutlinedIcon from '#material-ui/icons/AlternateEmailOutlined';
import NotificationsNoneOutlinedIcon from '#material-ui/icons/NotificationsNoneOutlined';
import DashboardOutlinedIcon from '#material-ui/icons/DashboardOutlined';
import ArchiveOutlinedIcon from '#material-ui/icons/ArchiveOutlined';
const drawerWidth = 280
const useStyles = makeStyles((theme) => ({
drawer : {
width: drawerWidth,
},
drawerPaper : {
width: drawerWidth,
},
list : {
marginLeft: '24px',
marginRight: '24px'
},
listItem : {
padding: '8px',
borderRadius: '5px',
},
text : {
color: theme.palette.primary.light,
fontWeight: '500',
lineHeight: '2000'
},
title : {
color: theme.palette.primary.light,
textAlign: 'center',
display: 'block',
fontWeight: '500',
fontSize: '20px',
marginTop: '10px',
marginBottom: '10px'
}
}));
export default function LeftBar(){
const classes = useStyles();
const [mobileOpen, setMobileOpen] = React.useState(false);
const handleDrawerToggle = () => {
setMobileOpen(!mobileOpen);
};
const list = [
{
text : 'Home',
icon : <HomeOutlinedIcon />,
path : '/'
},
{
text : 'Personal',
icon : <AlternateEmailOutlinedIcon />,
path : '/'
},
{
text : 'Notificatons',
icon : <NotificationsNoneOutlinedIcon />,
path : '/'
},
{
text : 'Dashboard',
icon : <DashboardOutlinedIcon />,
path : '/'
},
{
text : 'Archives',
icon : <ArchiveOutlinedIcon />,
path : '/'
}
];
return (
<Box>
<Drawer
className={classes.drawer}
anchor="left" classes={{
paper: classes.drawerPaper
}}
open={mobileOpen}
onClose={handleDrawerToggle}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
sx={{
display: { xs: 'block', sm: 'none' },
flexShrink: 0,
'& .MuiDrawer-paper': { boxSizing: 'border-box', width: drawerWidth },
}}
>
<Toolbar />
<Container>
<Typography variant="h5" component="h2" className={classes.title} gutterBottom>
My Account
</Typography>
</Container>
<Divider />
<List className={classes.list}>
{ list.map((item) => (
<ListItem key={item.text} className={classes.listItem} button>
<ListItemIcon className={classes.icon}>
{item.icon}
</ListItemIcon>
<ListItemText sx={{color: 'primary'}} primary={item.text} className={classes.text}/>
</ListItem>
))}
</List>
</Drawer>
</Box>
);
};
You have only included the drawer for xs - with display: { xs: 'block', sm: 'none' } that drawer will not display for any size but xs. You will need another drawer for sm and up. The MUI docs show a second drawer like this:
<Drawer
variant="permanent"
sx={{
display: { xs: 'none', sm: 'block' },
'& .MuiDrawer-paper': { boxSizing: 'border-box', width: drawerWidth },
}}
open
>
{you would put your list stuff here}
</Drawer>
You will probably need to move the Toolbar component outside of the Drawer component.

How to set search image icon in react-native-google-places-autocomplete?

How to set search image icon in react-native-google-places-autocomplete?
I want to know how i can set search image icon on left side in react-native-google-places-autocomplete.
I want output like this in below screen.So please help me.
But my design is like this.
Here is code of DiscoveryLocation.js file.
import React, { Component } from 'react'
import { Text, View, TouchableOpacity, TextInput, StyleSheet, Image } from 'react-native'
import { heightPercentageToDP as hp, widthPercentageToDP as wp } from 'react-native-responsive-screen';
import { RFPercentage, RFValue } from "react-native-responsive-fontsize";
import MapView, { PROVIDER_GOOGLE, Marker } from 'react-native-maps';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
console.disableYellowBox = true;
export default class DiscoveryLocation extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.vwheader} >
<TouchableOpacity
onPress={() => { this.props.navigation.goBack() }}
>
<Image source={require('../../Images/left-arrow-red.png')} style={{ height: 25, width: 30, marginTop: 22, marginLeft: 15, }}
/>
</TouchableOpacity>
<Text style={styles.txtdisloc}>Discovery Location </Text>
</View>
<View style={styles.mapcontainer}>
<MapView
provider={PROVIDER_GOOGLE}
style={styles.map}
region={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.015,
longitudeDelta: 0.0121,
}}
>
</MapView>
<View style={{ marginTop: hp('12%'), }}>
<GooglePlacesAutocomplete
placeholder='Enter City, State, Country'
minLength={2} // minimum length of text to search
autoFocus={false}
fetchDetails={true}
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
console.log(data);
console.log(details);
}}
getDefaultValue={() => {
return 'Mataram';
}}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: 'MY_API_KEY',
language: 'en', // language of the results
types: '(cities)' // default: 'geocode'
}}
styles={{
textInputContainer: {
width: wp('90%%'), height: hp('7%'), borderRadius: 11, borderTopWidth: 0,
borderBottomWidth: 0
},
textInput: {
marginLeft: 0,
marginRight: 0,
backgroundColor: 'D3D3D3'
},
description: {
fontWeight: 'bold',
},
predefinedPlacesDescription: {
color: '#1faadb'
},
powered: {
},
}}
filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
predefinedPlacesAlwaysVisible={true}
/>
</View>
</View>
<View style={{ marginTop: 10, marginBottom: 10 }}>
<TouchableOpacity style={styles.btn}>
<Text style={styles.txtbtn}>Confirm Location</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
I know this is late, but for the future ref There are props to add icons in GooglePlacesAutocomplete
renderLeftButton={() => <Image source={require('path/custom/left-icon')} />}
renderRightButton={() => <Text>Custom text after the input</Text>}
Here is the link for tutorial

Need to dynamically add items into a drawer menu in React Native

I need to have some items dynamically in my app's drawer after some categories get fetched from a json file (https://www.rallyssimo.it/wp-json/wp/v2/categories)
json example (I need that information)
[
{
"id": 44,
.
.
"name": "ALTRI RALLY",
.
.
},
Tis is the drawer:
const CustomDrawerComponent = (props) => (
<SafeAreaView style={{flex:1}}>
<View style={{height:80, backgroundColor: 'white', alignItems: 'center', justifyContent: 'center'}}>
<Image
source={{uri: 'https://www.rallyssimo.it/wp-content/uploads/2016/08/rallyssimo-logo.png'}}
style={{ height: 60, width: 180}}
/>
</View>
<ScrollView>
<DrawerItems {...props} />
</ScrollView>
</SafeAreaView>
)
const AppNavigator = createDrawerNavigator(
{
Home: DashboardStackNavigator,
},
{
contentComponent: CustomDrawerComponent
}
);
const AppContainer = createAppContainer(AppNavigator);
//Main class
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}
How can I put the items (I'm going to get from the JSON) in the drawer?
As you have noticed, you need to create your own custom drawer to achieve this, which is done with contentComponent: CustomDrawerComponent.
Now you cannot use DrawerItems within CustomDrawerComponent since you want full control on the items listed. But you can recreate the items yourself using basic and elements.
Finally you need to fetch the API and store the data in your state in order to render the result as a list in the drawer.
Here is a basic example for :
import React, { Component } from 'react';
import { ScrollView, Text, View, Image } from 'react-native';
import { NavigationActions } from 'react-navigation';
class CustomDrawerComponent extends Component {
constructor(props) {
super(props);
this.state = { data: null };
}
async componentDidMount() {
fetch('https://www.rallyssimo.it/wp-json/wp/v2/categories')
.then(res => res.json())
.then(data => this.setState({ data }))
}
navigateToScreen(routeName, params) {
return () => { this.props.navigation.dispatch(NavigationActions.navigate({ routeName, params })) };
}
render() {
if (this.state.data === null) {
return <Text>...</Text>;
}
return (
<View style={{ flex: 1, paddingTop: 30 }}>
<View style={{height:80, backgroundColor: 'white', alignItems: 'center', justifyContent: 'center'}}>
<Image
source={{uri: 'https://www.rallyssimo.it/wp-content/uploads/2016/08/rallyssimo-logo.png'}}
style={{ height: 60, width: 180}}
/>
</View>
<ScrollView>
<View>
{this.state.data.map(x => (
<Text
key={x.id}
style={{ fontSize: 16, lineHeight: 30, textAlign: 'center' }}
onPress={this.navigateToScreen('page2')}
>
{x.name}
</Text>
))}
</View>
</ScrollView>
</View>
);
}
}
export default CustomDrawerComponent;
And here is a working snack.

How to get the address from google maps autocomplete in React Native

I am using react-native-google-places-autocomplete to select a location. I want to extract the location selected and use it in other component.
How can I save the address
This is my code
import React, {Component} from 'react';
import { View, Image, Text, StyleSheet } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
const homePlace = { description: 'Home', geometry: { location: { lat: 48.8152937, lng: 2.4597668 } }};
const workPlace = { description: 'Work', geometry: { location: { lat: 48.8496818, lng: 2.2940881 } }};
export default class google extends Component {
render(){
return (
<View style={styles.container}>
<View style={styles.top}>
<GooglePlacesAutocomplete
placeholder='Search'
minLength={2} // minimum length of text to search
autoFocus={false}
returnKeyType={'search'} // Can be left out for default return key https://facebook.github.io/react-native/docs/textinput.html#returnkeytype
listViewDisplayed='auto' // true/false/undefined
fetchDetails={true}
renderDescription={row => row.description} // custom description render
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
console.log(data, details);
this.setState(
{
address: data.description, // selected address
coordinates: `${details.geometry.location.lat},${details.geometry.location.lng}` // selected coordinates
}
);
}}
getDefaultValue={() => ''}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: 'AIzaS#################',
language: 'es', // language of the results
}}
styles={{
textInputContainer: {
width: '100%'
},
description: {
fontWeight: 'bold'
},
predefinedPlacesDescription: {
color: '#1faadb'
}
}}
currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
currentLocationLabel="Current location"
nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
GoogleReverseGeocodingQuery={{
// available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
}}
GooglePlacesSearchQuery={{
// available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
rankby: 'distance',
types: 'food'
}}
filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
predefinedPlaces={[homePlace, workPlace]}
debounce={200} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
renderRightButton={() => <Text>Custom text after the input</Text>}
/>
</View>
<View style={styles.container2}>
<Text>
hola {this.setState.address}
</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
width: '100%',
height: '100%',
},
welcome: {
fontSize: 40,
textAlign: 'center',
margin: 10,
color:'black',
},
instructions: {
textAlign: 'center',
color: 'black',
marginBottom: 5,
},
top: {
height: '50%',
justifyContent: 'center',
alignItems: 'center',
},
container2: {
height:'75%',
justifyContent: 'center',
},
buttonContainer: {
alignItems: 'center',
backgroundColor: 'rgba(255, 255,255, 0.5)',
padding: 1,
margin: 50,
borderRadius: 25,
borderWidth: 2,
borderColor: '#0B0B3B'
},
textoboton: {
textAlign: 'center',
color: 'black',
marginBottom: 5,
fontSize: 12
},
})
I've been also using another library with some differences
app.js
import React,{Component} from 'react';
import { Constants } from 'expo';
import Icon from 'react-native-vector-icons/FontAwesome';
import { View, Image, Text, StyleSheet, AsyncStorage, Button,ScrollView, TextInput, ActivityIndicator } from 'react-native';
import {
NavigationActions
} from 'react-navigation';
import { GoogleAutoComplete } from 'react-native-google-autocomplete';
import {Card, Input} from "react-native-elements";
import LocationItem from './locationItem';
export default class App extends React.Component {
state={
datos:[],
}
componentDidMount(){
this._loadedinitialstate().done();
}
_loadedinitialstate =async() => {
AsyncStorage.getItem('datos');
}
render() {
return (
<View style={styles.container}>
<GoogleAutoComplete apiKey={'AIzaSyB2HyNTBm1sQJYJkwOOUA1LXRHAKh4gmjU'} debounce={20} minLength={2} getDefaultValue={() => ''} onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
console.log(data, details);}} returnKeyType={'default'} fetchDetails={true}
>
{({
locationResults,
isSearching,
clearSearchs,
datos,
handleTextChange
}) => (
<React.Fragment>
<View style={styles.inputWrapper}>
<Input
style={styles.textInput}
placeholder="Ingresa tu direccion"
onChangeText={(datos) => this.setState({datos})}
value={datos}
/>
</View>
{isSearching && <ActivityIndicator size="large" color="red" />}
<ScrollView>
{locationResults.map(el => (
<LocationItem
{...el}
key={el.id}
/>
))}
</ScrollView>
</React.Fragment>
)}
</GoogleAutoComplete>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
textInput: {
height: 40,
width: 300,
borderWidth: 1,
paddingHorizontal: 16,
},
inputWrapper: {
marginTop: 80,
flexDirection: 'row'
},
});
locationitem.js
import React, { PureComponent } from 'react';
import { View, Alert, Text, StyleSheet, TouchableOpacity, AsyncStorage} from 'react-native';
class LocationItem extends PureComponent {
constructor(props) {
super(props);
this.state = {datos:''};
}
_handlePress = () => {
AsyncStorage.setItem('datos',datos)
}
render() {
return (
<TouchableOpacity style={styles.root} onPress={this._handlePress} >
<Text value={this.state.datos}> {this.props.description} </Text>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
root: {
height: 40,
borderBottomWidth: StyleSheet.hairlineWidth,
justifyContent: 'center'
}
})
export default LocationItem;
The source of both codes is here react-native-google-places-autocomplete enter link description here
Which code will be easy to use, and How can I solve my Issue (get the address) ??
Any Answer will be Helpful
first install
npm i react-native-google-places-autocomplete
then
import React from 'react';
import { View, Image } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
const homePlace = { description: 'Home', geometry: { location: { lat: 48.8152937, lng: 2.4597668 } }};
const workPlace = { description: 'Work', geometry: { location: { lat: 48.8496818, lng: 2.2940881 } }};
const GooglePlacesInput = () => {
return (
<GooglePlacesAutocomplete
placeholder='Search'
minLength={2} // minimum length of text to search
autoFocus={false}
returnKeyType={'search'} // Can be left out for default return key https://facebook.github.io/react-native/docs/textinput.html#returnkeytype
listViewDisplayed='auto' // true/false/undefined
fetchDetails={true}
renderDescription={row => row.description} // custom description render
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
console.log(data, details);
}}
getDefaultValue={() => ''}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: 'YOUR API KEY',
language: 'en', // language of the results
types: '(cities)' // default: 'geocode'
}}
styles={{
textInputContainer: {
width: '100%'
},
description: {
fontWeight: 'bold'
},
predefinedPlacesDescription: {
color: '#1faadb'
}
}}
currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
currentLocationLabel="Current location"
nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
GoogleReverseGeocodingQuery={{
// available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
}}
GooglePlacesSearchQuery={{
// available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
rankby: 'distance',
types: 'food'
}}
filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
predefinedPlaces={[homePlace, workPlace]}
debounce={200} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
renderLeftButton={() => <Image source={require('path/custom/left-icon')} />}
renderRightButton={() => <Text>Custom text after the input</Text>}
/>
);
}
After a long journey, these steps helped me solve the problem.
1) Install npm install react-native-google-places-autocomplete --save.
2) Then use this code below, as an element in your component.
<GooglePlacesAutocomplete
query={{
key: "GOOGLE_PLACES_API_KEY",
language: "en", // language of the results
}}
onPress={(data, details = null) => {
console.log(details);
console.log(data);
console.log("data.description",data.description.split(','));
}}
onFail={(error) => console.error(error)}
listViewDisplayed="false"
requestUrl={{
url:
"https://cors-
anywhere.herokuapp.com/https://maps.googleapis.com/maps/api",
useOnPlatform: "web",
}} // this in only required for use on the web. See https://git.io/JflFv
more for details.
styles={{
textInputContainer: {
backgroundColor: "rgba(0,0,0,0)",
borderTopWidth: 0,
borderBottomWidth: 0,
},
textInput: {
marginLeft: 0,
marginRight: 0,
height: 38,
color: "#5d5d5d",
fontSize: 16,
},
predefinedPlacesDescription: {
color: "#1faadb",
},
}}
/>
3) You may have the same problem that i had, which the list disappears when i try to select result. However, this is the action that solved this problem for me.
Commenting out onBlur on node_modules. path: "..\node_modules\react-native-google-places-autocomplete\GooglePlacesAutocomplete.js".
...
onFocus={onFocus ? () => {this._onFocus(); onFocus()} : this._onFocus}
// onBlur={this._onBlur}
underlineColorAndroid={this.props.underlineColorAndroid}
...
4) For saving the address you can check the console.log in the code, and then use setState or something like this.
5) For more information and options of these element check out this repository:
https://github.com/FaridSafi/react-native-google-places-autocomplete.
hope this will help for you :)
First of all, I used listViewDisplayed={false} because otherwise the list view get stuck with the results, and even on location press the list doesn't closes.
Second, to answer your question: The results are in the onPress function of GooglePlacesAutocomplete, you can update the state with the chosen location and then use it where ever you want in your component:
onPress={(data, details = null) => {
this.setState({
latitude: details.geometry.location.lat,
longitude: details.geometry.location.lng,
moveToUserLocation: true
});
this._gotoLocation();
}
}
As i wrote it, onPress also trigger the function that moves the map to display the new location.
import React, {Component} from 'react';
import { View, Image, Text, StyleSheet } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
export default class google extends Component {
constructor(props) {
super(props);
this.state = {
address:null,
lat:null,
lng:null,
}
}
getAdd(data){
console.log("add",data);
this.setState(
{
address: data.formatted_address, // selected address
lat: data.geometry.location.lat,// selected coordinates latitude
lng:data.geometry.location.lng, // selected coordinates longitute
}
);
console.log("this.state.address",this.state.address); ///to console address
console.log("this.state.coordinates",this.state.lat,this.state.lng); /// to console coordinates
}
render(){
return (
<View style={styles.container}>
<View style={styles.top}>
<GooglePlacesAutocomplete
placeholder='Search'
minLength={2} // minimum length of text to search
autoFocus={false}
fetchDetails={true}
returnKeyType={'default'}
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
var data = details;
this.getAdd(data);
}}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: 'AIzaS#################',
language: 'en',
types: 'geocode', // default: 'geocode'
}}
listViewDisplayed={this.state.showPlacesList}
textInputProps={{
onFocus: () => this.setState({ showPlacesList: true }),
onBlur: () => this.setState({ showPlacesList: false }),
}}
styles={{
textInputContainer: {
width: '100%'
},
description: {
fontWeight: 'bold'
},
predefinedPlacesDescription: {
color: '#1faadb'
}
}}
currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
currentLocationLabel="Current location"
nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
// predefinedPlaces={[]}
predefinedPlacesAlwaysVisible={true}
/>
</View>
{ this.state.address !=null ?(
<View style={styles.container2}>
<Text>
Address: {this.state.address}
</Text>
</View>
):null }
</View>
);
}
}
const styles = StyleSheet.create({
container: {
width: '100%',
height: '100%',
},
welcome: {
fontSize: 40,
textAlign: 'center',
margin: 10,
color:'black',
},
instructions: {
textAlign: 'center',
color: 'black',
marginBottom: 5,
},
top: {
height: '50%',
justifyContent: 'center',
alignItems: 'center',
},
container2: {
height:'75%',
justifyContent: 'center',
},
buttonContainer: {
alignItems: 'center',
backgroundColor: 'rgba(255, 255,255, 0.5)',
padding: 1,
margin: 50,
borderRadius: 25,
borderWidth: 2,
borderColor: '#0B0B3B'
},
textoboton: {
textAlign: 'center',
color: 'black',
marginBottom: 5,
fontSize: 12
},
})