How to get the user location in react-native-mapbox-gl? - javascript

i'm using react-native-mapbox-gl to show the map in my react app, on page load it should show the location of the user like how the google maps shows, but it fails to show instead it will show some other region of the map,
Can someone help?
Thanks in advance.
here is the snippet
import { StyleSheet, View } from "react-native";
import MapboxGL from "#react-native-mapbox-gl/maps";
MapboxGL.setAccessToken("<YOUR_ACCESSTOKEN>");
const styles = StyleSheet.create({
page: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF"
},
container: {
height: 300,
width: 300,
backgroundColor: "tomato"
},
map: {
flex: 1
}
});
export default class App extends Component {
componentDidMount() {
MapboxGL.setTelemetryEnabled(false);
}
render() {
return (
<View style={styles.page}>
<View style={styles.container}>
<MapboxGL.MapView style={styles.map} />
<MapboxGL.UserLocation />
</View>
</View>
);
}
}

You can pass children the MapboxGL.Mapview.
<MapboxGL.MapView style={styles.map}>
<MapboxGL.UserLocation/>
</MapboxGL.MapView>

Check this article that shows how to display user location marker using Marker component.
https://github.com/react-native-mapbox-gl/maps/issues/227
https://github.com/react-native-community/react-native-maps/blob/master/docs/marker.md
react-native mapbox is not showing user location and annotation

For me, it works(was showing the wrong location as of now):
<MapboxGL.MapView style={styles.map} zoomEnabled logoEnabled={false}>
<MapboxGL.UserLocation visible={true} />
</MapboxGL.MapView>
For more information you can refer to official docs.
https://github.com/nitaliano/react-native-mapbox-gl/blob/master/docs/MapView.md
https://github.com/rnmapbox/maps/blob/main/docs/UserLocation.md
P.S: MapboxGL.MapView has one props showUserLocation but it seems now working now,
I also tried several other props as mentioned in docs they are also not working, look docs are not updated!!

Related

React Native - Animate width shrink

In the header of my React Native app, I have a conditional icon and a Searchbar.
static navigationOptions = ({ navigation }) => {
const { params = {} } = navigation.state;
return {
headerTitle: (
<View
style={{
flex: 1,
backgroundColor: Platform.OS === 'ios' ? '#e54b4d' : '',
alignItems: 'center',
flexDirection: 'row',
paddingHorizontal: 10,
height: StatusBar.currentHeight,
}}>
{params.isIconTriggered && <Icon name="chevron-left" size={28} />}
<SearchBar
round
platform={'default'}
placeholder="Search"
containerStyle={{
flex: 1,
backgroundColor: 'transparent',
}}
/>
</View>
),
headerStyle: {
backgroundColor: '#e54b4d',
},
};
};
Normally the Searchbar will take the full width of the header which is what I want. If the condition isIconTriggered is true, an icon will appear in front of the Searchbar and the width of the SearchBar will shrink enough so that the icon is visible next to it.
However, there is no transition or animation when this happens and it does not feel nor look nice. I would like to add an animation to the Searchbar so the width shrinks gradually and smoothly when the condition is triggered and the icon appears.
Is that possible to achieve and how can I achieve this?
Try to learn Animated API of react native.
Here is how i done it with button trigger.
import React, {Component} from 'react';
import {StyleSheet, View, TextInput , Button, SafeAreaView, Animated} from 'react-native';
import FA from 'react-native-vector-icons/FontAwesome5'
const AnimatedIcon = Animated.createAnimatedComponent(FA)
// make your icon animatable using createAnimatedComponent method
export default class Application extends Component {
animVal = new Animated.Value(0);
// initialize animated value to use for animation, whereas initial value is zero
interpolateIcon = this.animVal.interpolate({inputRange:[0,1], outputRange:[0,1]})
interpolateBar = this.animVal.interpolate({inputRange:[0,1],outputRange:['100%','90%']})
// initialize interpolation to control the output value that will be passed on styles
// since we will animate both search bar and icon. we need to initialize both
// on icon we will animate the scale whereas outputRange starts at 0 end in 1
// on search bar we will animate width. whereas outputRange starts at 100% end in 90%
animatedTransition = Animated.spring(this.animVal,{toValue:1})
// we use spring to make the animation bouncy . and it will animate to Value 1
clickAnimate = () => {
this.animatedTransition.start()
}
// button trigger for animation
//Components that will use on Animation must be Animated eg. Animted.View
render() {
return (
<SafeAreaView>
<View style={styles.container}>
<View style={styles.search}>
{/* our icon */}
<Animated.View style={{width: this.interpolateBar}}>
<TextInput placeholder='search here' style={styles.input}/>
</Animated.View>
<AnimatedIcon name='search' size={28} style={{paddingLeft: 10,paddingRight:10, transform:[{scale: this.interpolateIcon}]}}/>
</View>
<Button title='animate icon' onPress={this.clickAnimate}/>
</View>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor:'#F79D42',
// flex: 1,
height:'100%',
paddingTop:20,
flexDirection: 'column',
// justifyContent: 'center',
alignItems:'center'
},
input:{
width: '100%',
height:40,
backgroundColor:'gray',
textAlign:'center'
},
search:{
flexDirection:'row-reverse',
width:'90%',
height:40,
alignItems:'center'
}
});
Solution using react-native-elements SearchBar component.
Wrapped the SearchBar Component inside Animated.View.
to explicitly animate the search bar
Like This:
<Animated.View style={{width: this.interpolateBar}}>
<SearchBar
placeholder="Type Here..."
containerStyle={{width: '100%'}}
/>
</Animated.View>
You can achieve this using Animated API of React Native.
You can check this tutorial for an overview of changing the size of elements with animation.
React-Native-Animatable is super cool!
Try this one out:
Create A custom animation object
import * as Animatable from 'react-native-animatable';
Animatable.initializeRegistryWithDefinitions({
const myAnimation = {
from: {
width: 200
},
to: {
width: 100
}
}
})
Use is as Animation value within a view or as a reference within a function call.
Within a view:
<Animatable.View useNativeDriver animation={myAnimation}/>
As a reference variable:
<Animatable.View useNativeDriver ref={ref=>(this.testAnimation = ref)}/>
Method:
testMethod = () => {
this.testAnimation.myAnimation();
}

React Native: Can't style the Button

I am quite new to React Native. I am familiar with React and use it for my work. React Native seems different in terms of applying styles to the components.
I am having issue applying styles to the button.
Here is my current code:
<Button
title="LET'S GET STARTED"
onPress={() => {
console.log('You tapped the Decrypt button!');
}}
buttonStyle={{
backgroundColor: "#0A6ABB",
width: 300,
height: 45,
borderColor: "#FFFFFF",
borderWidth: 2,
borderRadius: 5
}}
containerStyle={{ marginTop: 50 }}
/>
I tried multiple ways, but the styles are not being applied the button that I have created.
Here is the screenshot of how it looks like:
"Let's get started" is the button and no matter what it just has the default blue text.
How can I fix this?
Could anyone please help me with this?
Is your Button component imported from react-native? If yes then you can't style it because as stated on their documentation, below are the supported props, buttonStyle is not supported prop. Alternatively, maybe you can try other packages like Button from react-native-elements or NativeBase
onPress
title
accessibilityLabel
color
disabled
testID
hasTVPreferredFocus
Button is very limited in react native. You can use TouchableOpacity instead to give you more flexibility See documentation here.
TouchableOpacity example:
render () {
return (
<TouchableOpacity
style={styles.button}
onPress={this.onPress} >
<Text> LETS GET STARTED </Text>
</TouchableOpacity>
)
}
const styles = StyleSheet.create({
button: {
alignItems: 'center',
backgroundColor: '#DDDDDD',
padding: 10
},
});
There are also different kinds of "buttons" depending on what you need like TouchableHighlight, TouchableWithoutFeedback
Use TouchableOpacity
import { StyleSheet, TouchableOpacity, Text }
render() {
return (
<TouchableOpacity
style={styles.button}
onPress={() => { console.log('You tapped the Decrypt button!'); }}
>
<Text> LET'S GET STARTED </Text>
</TouchableOpacity>
)
}
const styles = StyleSheet.create({
button: {
alignItems: 'center',
backgroundColor: "#0A6ABB",
width: 300,
height: 45,
borderColor: "#FFFFFF",
borderWidth: 2,
borderRadius: 5,
marginTop: 50
},
});

YouTube full screen is on top of everything else in React Native

I'm embedding YouTube videos in a React Native app and when that component mounts, YouTube opens a full screen video to play. That part is great. I want a full screen video.
The problem is that it puts it on top of every other single React Native component. I can't get any interaction feedback from the user. Even when I put a component at the top-most level with the highest z-index possible, the YouTube video still covers it.
I'd like the user to be able to swipe left or right to go to another video (I have the swiping part figured out, though it's not shown here). Is this even possible? How can I do this?
[Edit: Also, does anyone have any resources about how YouTube can put itself in front of all other components, including its iframe's parents?]
The code:
import React from 'react';
import { StyleSheet, Text, View, WebView } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View id={'webRoot'} style={styles.container}>
<WebView
ref={'webview'}
automaticallyAdjustContentInsets={false}
source={{uri: 'https://www.youtube.com/watch?v=43w7rcYPUnI'}}
javaScriptEnabled={true}
domStorageEnabled={true}
decelerationRate='normal'
startInLoadingState={true}
style={{zIndex: -1}} />
<Text style={{
position: 'absolute',
height: 300,
width: 300,
top: 0,
zIndex: 8999999999999999999
}}>
{"Won't be visible"}
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});

undefined is not an object (evaluating 'state.cameraType')

I'm trying to get a React Native app set up following this post and then ported over to ES6. Here's the main page code:
"use strict";
import React, { Component } from 'react';
import Camera from 'react-native-camera';
import {
AppRegistry,
StyleSheet,
Text,
View,
TextInput,
TouchableHighlight,
} from 'react-native';
export default class AwesomeProject extends Component {
constructor(props) {
super(props);
this.state = {cameraType: Camera.constants.Type.back};
}
render() {
return (
<Camera
ref="cam"
style={styles.container}
type={this.state.cameraType}>
<View style={styles.buttonBar}>
<TouchableHighlight style={styles.button} onPress={this._switchCamera.bind(this)}>
<Text style={styles.buttonText}>Flip</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.button} onPress={this._takePicture.bind(this)}>
<Text style={styles.buttonText}>Take</Text>
</TouchableHighlight>
</View>
</Camera>
);
}
_switchCamera: () => {
var state = this.state;
console.log(this.state);
state.cameraType = state.cameraType === Camera.constants.Type.back ? Camera.constants.Type.front : Camera.constants.Type.back;
this.setState(state);
}
_takePicture: () => {
console.log(this.refs);
this.refs.cam.capture(function(err, data) {
console.log(err, data);
});
}
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "transparent",
},
buttonBar: {
flexDirection: "row",
position: "absolute",
bottom: 25,
right: 0,
left: 0,
justifyContent: "center"
},
button: {
padding: 10,
color: "#FFFFFF",
borderWidth: 1,
borderColor: "#FFFFFF",
margin: 5
},
buttonText: {
color: "#FFFFFF"
}
});
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
I am getting a weird error saying both state.cameraType is undefined and this.refs is undefined. I have a hunch that something is not getting bound and my this is not pointing to right thing but I have tried using both arrow functions and explicitly binding. See comment below. Anyway, I am not sure why it's acting up, any ideas?
Very similar to this post except I have tried both the proposed solutions so I feel like something else is missing or I'm doing the binding wrong.
edit: Is there reason to be downvoted? Am I not being clear on something :o
It turns out manual binding is the way to go, just needed to reload the app. I did not have hot-swapping enabled. Alternatively, arrow functions should also work.
Another thing to point out, for iOS 10 and above, you'll have to set 2 things in the Info.plist file, Privacy - Camera Usage Description and Privacy - Photo Library Usage. It can be any string value.

TabBarIOS in ReactNative not working, items overlapping each other

So im making an app and this is my code:
import React, { Component } from 'react';
import {
View,
Text,
TabBarIOS,
StyleSheet,
Dimensions
} from 'react-native';
//import Styles from './LayoutStyle.js';
class Layout extends Component {
constructor(){
super()
this.state = {selectedTab: 'tabThree'}
}
setTab(tabId){
this.setState({selectedTab: tabId})
}
render() {
return(<View style={Styles.Layout}>
<TabBarIOS>
<TabBarIOS.Item
systemIcon='history'
selected={this.state.selectedTab === 'tabOne'}
onPress={() => this.setTab('tabOne')}>
<View>
<Text>Jure1</Text>
</View>
</TabBarIOS.Item>
<TabBarIOS.Item
systemIcon='bookmarks'
selected={this.state.selectedTab === 'tabTwo'}
onPress={() => this.setTab('tabTwo')}>
<View>
<Text>Jure2</Text>
</View>
</TabBarIOS.Item>
<TabBarIOS.Item
systemIcon='more'
selected={this.state.selectedTab === 'tabThree'}
onPress={() => this.setTab('tabThree')}>
<View>
<Text>Jure3</Text>
</View>
</TabBarIOS.Item>
</TabBarIOS>
</View>
);
}
}
const Styles = StyleSheet.create({
Layout: {
alignItems: "center",
justifyContent: "center",
height: Dimensions.get('window').height,
width: Dimensions.get('window').width,
},
TabBar: {
backgroundColor: 'grey'
}
});
export default Layout;
Well what i expected was an app where you have a TabBar on the bottom with three different items to choose from and it should look like i would in a native ios app. Well thats not the case, what i get is this:
Well what should i do? How do i style this item to not overlap? Any ideas?
The layout style is causing the inner content to get centred oddly, change Layout style to this:
Layout: {
flex:1,
}
Additionally, when trying to draw a scene from the tab clicked you will want to use a render function inside the TabBarIOS.Item object, react native provides some good examples of how to do this in the documentation: https://facebook.github.io/react-native/docs/tabbarios.html
I would highly recommend placing a navigator for each object which allows you to have much more control over the scene changes:
<TabBarIOS.Item
systemIcon='history'
title= 'Jure1'
selected={this.state.selectedTab === 'tabOne'}
onPress={() => this.setTab('tabOne')}>
<View style = {{flex:1}}>
<Navigator
renderScene={this._renderScene}
/>
</View>
</TabBarIOS.Item>

Categories

Resources