React Native mapbox | react-native-mapbox-gl |How to change PointAnnotation Image and Callout is not touchable in Android? - react-native

I am trying to change the default Mapbox pin icon on Android as in iOS I'm getting the expected result.
Issue
Not able to change PointAnnotation Icon(Using PNG format)
Callout image is also not loading(Using PNG format)
Not able to click on callout.
All the above issues I'm facing in Android only, iOS is working fine.
import React from 'react';
import {
View,
Image,
} from 'react-native';
import MapboxGL from '#react-native-mapbox-gl/maps';
const currentLatLng = [
[-74.00597, 40.71427]
];
class BugReportExample extends React.Component {
render() {
return (
View style={{flex: 1}}>
<MapboxGL.MapView
ref={c => (this._map = c)}
logoEnabled={false}
style={{flex: 1}}>
<MapboxGL.Camera
ref={c => (this.camera = c)}
zoomLevel={14}
centerCoordinate={currentLatLng}
/>
{/* User location */}
<MapboxGL.PointAnnotation
key={'9090'}
ref={ref => (this.userAnnotationRef = ref)}
id={'9090'}
coordinate={currentLatLng}
title="">
<View style={{ width: 45,height: 45,alignItems: 'center',justifyContent: 'center',overflow: 'hidden',}}>
<Image
source={{uri:'https://reactnative.dev/img/tiny_logo.png'}}
resizeMode={'contain'}
style={{height: wp('10%'), width: wp('10%')}}
onLoad={() => this.userAnnotationRef.refresh()}
/>
</View>
<MapboxGL.Callout title={'You'} />
</MapboxGL.PointAnnotation>
</MapboxGL.MapView>
</View>
);
}
}
This is working fine on iOS.
iOS Result
Android - Issue

const ImageMarker = ({ children }) =>
Platform.select({
ios: children,
android: (
<Text
style= {{
lineHeight: 60, // there is some weird gap, add 40+ pixels
// backgroundColor: '#dcdcde',
}}>
{ children }
< /Text>
),
});
<ImageMarker>
<Image
source={IMAGE_LINK}
style={{width: 45, height: 55}}
/>
</ImageMarker>

Load image before assigning it to the PointAnnotation.
const [imagesLoaded, setImagesLoaded] = useState(false);
setTimeout(() => {
setImagesLoaded(true);
}, 500);
const Example = () => {
render() {
return (
{imagesLoaded ?
// Your mabox code with PointAnnotation
:
<Image
source={{uri:'https://reactnative.dev/img/tiny_logo.png'}}
resizeMode={'contain'}
style={{height: wp('10%'), width: wp('10%'), opacity:0}}
/>
);
}
}

Related

how can i change the color of text and tint color of image of a components using props in react native?

I have made a custom button and below is the code.
export class MenuItems extends Component {
constructor(props) {
super(props);
this.state = {
loading: true
};
}
render() {
let { navigation, listingname, imagesource,} = this.props;
return (
<View >
<TouchableOpacity
onPress={this.props.onPress}
style={[styles.menuStyle]}>
<View style={{ flexDirection: 'row', }}>
<Image source={imagesource} style={[styles.menuItemIcon,{tintColor:'black'}]} />
<Text style={[styles.menuTextstyle]}>{listingname} </Text>
</View>
</TouchableOpacity>
</View>
);
}
}
export default MenuItems;
Now I have reused it with different value and images . I want to change the tint color and text color of the custom button to blue . Below is the code.
\<MenuItems listingname="Logout"
onPress={() => {
this.RBSheet.close();
// this.props.navigation.replace('HomeApp', { screen: 'Home' })
// navigation.dispatch(StackActions.popToTop());
// reset Notification counter
this.props.notifyCountrUpdtHndlr(0)
AuthHelpers.logout(this.props.navigation, true);
}}
imagesource ={IMAGE.LOGOUT_ICO}/>
</View>
I want the image color in blue using tint color and text color of the component in blue. kindly provide the solution and correct the code.
Use style
const StyledImage = ({style}) =>
<Image
style={{width: 20, height: 20, ...style}}
...
/>
<StyledImage style={{tintColor: 'blue'}} />
or custom prop
const TintedImage = ({tintColor}) =>
<Image
style={{width: 20, height: 20, tintColor: tintColor}}
...
/>
<TintedImage tintColor='red' />

url path with image variable in image source uri React Native

I am trying to display an Image in which the data was fetch from an api and render into a flatlist, I am trying to concat or connect the sting link with the variable, in the image source uri but did not work, how can I fix it.
<FlatList
data = {data}
keyExtractor={item => item.id}
showsVerticalScrollIndicator = {false}
renderItem={({item}) => {
return (
<Image
source={{ uri: `https://placewave.com/avatar/${item.user_image}` }}
resizeMode="cover"
style={styles.userImage}
/>
)
}}
/>
Thanks for the help
Unfortunately it will not work in such way.
Image must not have conditional source prop. Consider moving https://placewave.com/avatar/${item.user_image} to a variable and add condition to display some kind of fallback(like ActivityIndicator) until you will have valid user_image.
Complete test code
import * as React from 'react';
import { Image, Text, View, StyleSheet, FlatList } from 'react-native';
import Constants from 'expo-constants';
export default function App() {
const data = [{ id: 1, user_image: 'cute-boy-standing-little-white-background-40214306.jpg' }, { id: 1, user_image: 'no image url.jpg' }]
return (
<View >
<FlatList
data={data}
keyExtractor={item => item.id}
showsVerticalScrollIndicator={false}
renderItem={({ item }) => {
let uriVar
if (item.user_image) uriVar = `https://thumbs.dreamstime.com/b/${item.user_image}`
return (<View>
{uriVar != null ?
<Image source={{ uri: uriVar }}
style={styles.userImage}
/> : null} </View>)
}}
/>
<Text style={styles.paragraph}>
Hello
</Text>
</View>
);
}
const styles = StyleSheet.create({
userImage: {
width: '150px',
height: '150px',
borderWidth: 1
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
});
Thank you all for the respond, but I find the answer
First I define the url const URL = 'https://placewave.com/avatar';
Then Include it:
<Image
source={{ uri: URL + '/' + item.user_image}}
resizeMode="cover"
style={styles.userImage}
/>

undefined is not an object( evaluating 'state.selected.clip.clip') getting this error using Api in react Native

import React,{useState} from 'react';
import axios from 'axios';
import { Video } from 'expo-av';
import { StyleSheet, View,Text, TextInput, ScrollView, Image, TouchableHighlight, Modal, Button } from 'react-native';
export default function App() {
const apiurl = 'https://api.rawg.io/api/games?page_size=5';
const [state, setState] = useState({
s: 'Enter a movie ...',
results: [],
selected: [],
});
const search = () => {
axios(apiurl + '&search=' + state.s).then(({data}) => {
let results = data.results;
console.log(results);
setState(prevState => {
return {
...prevState,
results: results,
};
});
});
};
const openPopup = slug => {
axios('https://api.rawg.io/api/games/' + slug).then(({data}) => {
let result = data;
console.log(result);
setState(prevState => {
return {...prevState, selected: result};
});
});
};
return (
<View>
<Text> Game Search</Text>
<TextInput
onChangeText={text =>
setState(prevState => {
return {
...prevState,
s: text,
};
})
}
value={state.s}
onSubmitEditing={search}
/>
<ScrollView>
{state.results.slice(0, 1).map(result => (
<TouchableHighlight
key={result.slug}
onPress={() => openPopup(result.slug)}>
<View>
<Image
source={{uri: result.background_image}}
style={{
width: 250,
height: 250,
alignItems: 'center',
justifyContent: 'center',
}}
resizeMode="cover"
/>
<Text>{result.name}</Text>
</View>
</TouchableHighlight>
))}
</ScrollView>
<Modal
animationType="fade"
transparent={false}
visible={typeof state.selected.name != 'undefined'}>
<ScrollView>
<View>
<Text>{state.selected.name}</Text>
<Image
source={{uri: state.selected.background_image}}
style={{
margin: 20,
width: '90%',
height: 300,
alignItems: 'center',
justifyContent: 'center',
}}
resizeMode="cover"
/>
<Video
source={{uri: state.selected.clip.clip}}
rate={1.0}
volume={1.0}
resizeMode="cover"
shouldPlay
isLooping
style={{width: 300, height: 300}}
/>
</View>
</ScrollView>
<Button
onPress={() =>
setState(prevState => {
return {...prevState, selected: {}};
})
}
title="Close"
/>
</Modal>
</View>
);
}
Whenever I run it, it gives me this error message for the clip otherwise don't get an error message for the image or name or anything else. Does anyone know how to solve it? It's a simple app and all the codes are in App.js
Here I have attached the image of the error that I am getting. I am using RawG API to create a simple Game-search app
Screenshot of that error
You need to handle the case where state.selected.clip is null or undefined. You can do that like this:
{
state.selected.clip && (
<Video
source={{uri: state.selected.clip.clip}}
rate={1.0}
volume={1.0}
resizeMode="cover"
shouldPlay
isLooping
style={{width: 300, height: 300}}
/>
);
}
Problems will occur when you haven't selected anything yet or if there is a game that doesn't have a clip. So you shouldn't render the Video component if this value is not properly set.

React native carousel item active index

I've just started learning react native and I want to make a splash screen that contains a slider with dots. But when I scroll the scrollview the active dot doesn't change properly. My slider component is like below
export default function Slider() {
const [active, setActive] = useState(0);
const onChange = ({ nativeEvent }) => {
const active = Math.floor(
nativeEvent.contentOffset.x / nativeEvent.layoutMeasurement.width
);
setActive({ active });
console.log(active);
};
return (
<View style={styles.container}>
<ScrollView
onMomentumScrollEnd={onChange}
horizontal
pagingEnabled
showsHorizontalScrollIndicator={false}
>
{dummyData.map((item, index) => {
return (
<SliderItem
key={index}
title={item.title}
image={item.url}
description={item.description}
/>
);
})}
</ScrollView>
<View style={styles.dotView}>
{dummyData.map((k, i) => (
<View
key={i}
style={{
backgroundColor: i === active ? "red" : "blue", // My problem is here
height: 10,
width: 10,
margin: 8,
borderRadius: 6,
}}
/>
))}
</View>
</View>
);
}
Change setActive({ active }); to setActive(active);

KeyboardAvoidingView works on EXPO but not on APK?

I bought this Theme which in Expo works flawlessly, but as soon as I build the APK, the Keyboard will cover the whole screen and wont work as supposed.
I'm using expo for testing and it works just fine.
return (
<SafeAreaView style={styles.container}>
<NavHeader title={thread.name} {...{navigation}} />
<FlatList
inverted
data={messages}
keyExtractor={message => `${message.date}`}
renderItem={({ item }) => (
<Msg message={item} name={item.me ? name : thread.name} picture={thread.picture} />
)}
/>
<KeyboardAvoidingView behavior={Platform.OS === "ios" ? "padding" : "height"} enabled>
<View style={styles.footer}>
<TextInput
style={styles.input}
placeholder="Write a message"
value={this.state.message}
onChangeText={message => this.setState({ message })}
autoFocus
blurOnSubmit={false}
returnKeyType="send"
onSubmitEditing={this.send}
underlineColorAndroid="transparent"
/>
<TouchableOpacity primary transparent onPress={this.send}>
<Text style={styles.btnText}>Send</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
</SafeAreaView>
);
And the Styles
const styles = StyleSheet.create({
container: {
flex: 1
},
footer: {
borderColor: Theme.palette.lightGray,
borderTopWidth: 1,
paddingLeft: Theme.spacing.small,
paddingRight: Theme.spacing.small,
flexDirection: "row",
alignItems: "center"
},
input: {
height: Theme.typography.regular.lineHeight + (Theme.spacing.base * 2),
flex: 1
},
btnText: {
color: Theme.palette.primary
}
});
I have tried the following plugin
using the enableOnAndroid prop
https://github.com/APSL/react-native-keyboard-aware-scroll-view
with no success.
I have posted here:
https://github.com/APSL/react-native-keyboard-aware-scroll-view/issues/305
and here:
https://github.com/expo/expo/issues/2172
Unfortunately this is a known issue
https://github.com/expo/expo/issues/2172
Depending on the complexity of your screen layout you could add a bottom margin or padding using Keyboard listeners provided by React Native.
import React, { Component } from 'react';
import { Keyboard, TextInput } from 'react-native';
class Example extends Component {
componentDidMount () {
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow);
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
}
componentWillUnmount () {
this.keyboardDidShowListener.remove();
this.keyboardDidHideListener.remove();
}
_keyboardDidShow () {
this.setState({
marginBottom: 400
})
}
_keyboardDidHide () {
this.setState({
marginBottom: 0
})
}
render() {
return (
<TextInput
style={{marginBottom: this.state.marginBottom}}
onSubmitEditing={Keyboard.dismiss}
/>
);
}
}