MapView inside a react-native-snap-carousel - react-native

i have implemented react-native-maps inside carousel view to show floor plans of a 2-floor building, and everything is working fine.
Now when i try to call a function to re-centre the floor-plan image, first slide is not getting responsive to the function whereas the second slide works fine and as expected.
if(Platform.OS === 'ios'){
console.log("mapview" ,mapView);
return (
<View style={styles.container} key={index}>
<MapView
style={{
height:Dimensions.get('window').height,
width:Dimensions.get('window').width
}}
ref={mapView}
provider={PROVIDER_GOOGLE}
mapType= "none"
minZoomLevel = {16}
maxZoomLevel = {18}
initialRegion={{
latitude:mapcenterlat,
latitudeDelta: 0.009,
longitude:mapcenterlng,
longitudeDelta:0.0315,
}}>
<Overlay
bounds={[
[coord_topleft_lat, coord_topleft_lng],
[coord_bottomright_lat, coord_bottomright_lng]
]}
image= {item.floorplan_image}
/>
{item.locations.map((polygon,index) =>
(<MapView.Polygon
key={polygon.index}
coordinates={polygon.coordinates}
fillColor={polygon.fillcolor}
fillOpacity={2}
strokeColor={polygon.strokecolor}
tappable = {true}
strokeOpacity= {1}
strokeWeight={1}
onPress={() => createBooking(polygon.id,polygon.name,polygon.is_reserved,polygon.assets)}
/>),
)}
</MapView>
<View style={{position: 'absolute',flexDirection:'row',padding:70,marginVertical:-50}}>
<Text style={{fontWeight: 'bold', fontSize: 20}}>
{item.floor_name}
</Text>
<Pagination
dotsLength={floorlist.length}
activeDotIndex={activeSlide}
carouselRef={isCarousel}
dotStyle={{
width: 10,
height: 10,
borderRadius: 5,
marginHorizontal: 0,
backgroundColor: 'rgba(0, 0, 0, 0.92)'
}}
inactiveDotOpacity={0.4}
inactiveDotScale={0.6}
tappableDots={true}
activeOpacity= {1}
/>
</View>
<View style={{position: 'absolute',flexDirection:'column',top:hp('33%'),marginHorizontal:10}}>
<TouchableOpacity onPress={() => _carousel.snapToPrev()}><AntDesign name="left" size={24} color="black" /></TouchableOpacity>
<TouchableOpacity onPress={() => _carousel.snapToNext()}><AntDesign name="right" size={24} color="black" /></TouchableOpacity>
)
}

Related

What is the possible reason of why react native MapView is lagging?

My app have structure like this,
MapPage.js that contain expo-barcode-scanner wrapped with Modal and MapView.
DetailsPage.js that contain search result/products' details.
User can use the barcode scanner or TextInput(also in MapPage, not wrapped in Modal) to search product ID and the app will navigate to DetailsPage for result. If result is not found, app will automatically navigate.goBack() to MapPage. If result existed, will goto the result and stay in DetailsPage.
User can also navigate to DetailsPage by pressing marker callout on MapView.
Here is situation:
user press on marker callout(navigate to DetailsPage), then press back(navigate.goBack()) to MapPage : No lagging
user search by TextInput, then back to MapPage: No lagging whether search result exist or not
user search by Barcode, result not exist, automatically back to MapPage: not lagging
user search by Barcode, result existed, stay in DetailsPage, user manually press back: LAGGING
Below codes for your references
//MapPage
<MapView
style={{ width: '100%', height: '100%' }}
provider={PROVIDER_GOOGLE}
showsMyLocationButton={true}
showsUserLocation={true}
region={{
latitude: region.latitude,
longitude: region.longitude,
latitudeDelta: region.latitudeDelta,
longitudeDelta: region.longitudeDelta,
}}>
<MapMarker
markerLocation={markers}
countryCode={country.countryCode}
/>
</MapView>
...
<TextInput
placeholder={
i18n.t('SearchId')
}
placeholderTextColor="white"
onSubmitEditing={() =>
handleBarCodeScanned({ data: textSearchData })
}
onChangeText={(text) => {
settextSearchData(text.toUpperCase());
}}
/>
<Pressable onPress={() => setqrcodeModalVisi(true)}>
<Ionicons
name="qr-code-outline"
size={33}
color="white"
/>
</Pressable>
...
<Modal
visible={qrcodeModalVisi}
animationType="slide"
onRequestClose={() => setqrcodeModalVisi(false)}
transparent={true}>
<View>
<Pressable onPress={() => setqrcodeModalVisi(false)}>
<Feather
name="x"
size={24}
color="white"
/>
</Pressable>
{!hasPermission && (
<View>
<Text
style={{
color: colors.text,
}}>
Camera access denied.
</Text>
<Pressable onPress={() => getBarCodeScannerPermissions()}>
<Text style={{ color: colors.secondary }}>
Goto setting page
</Text>
</Pressable>
</View>
)}
{hasPermission && (
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}}>
<BarCodeScanner
onBarCodeScanned={
scanned ? undefined : handleBarCodeScanned
}
style={{
width: '100%',
height: '80%',
}}
/>
</View>
)}
</View>
</Modal>
//MapMarker
<View>
{markerLocation.map((array) => (
<Marker
key={array.title}
coordinate={{
latitude: array.latitude,
longitude: array.longitude,
}}
image={require('../../../assets/icons/map_marker.png')}
title={''}
description={''}
onCalloutPress={() => handleMapMarkerPress(array.regionCode)}>
<Callout>
<View
style={{
backgroundColor: 'white',
width: 180,
paddingVertical: 5,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
width: '80%',
textAlign: 'center',
color: colors.secondary,
fontWeight: 'bold',
}}>
{array.title}
</Text>
<View
style={{
backgroundColor: colors.secondary,
width: '80%',
height: 25,
alignItems: 'center',
justifyContent: 'center',
marginTop: 2,
flexDirection: 'row',
marginVertical: 5,
}}>
<Text style={{ color: 'white', fontWeight: 'bold' }}>
{i18n.t('MapMarkerBtn')}
</Text>
</View>
</View>
</Callout>
</Marker>
))}
</View>
Thanks!

React-native Modal component animation

Is there any way to make Modal appear from left to right?
Right now I have this and its only sliding from bottom to top:
<Modal animationType={'slide'} visible={showModal}>
<View
style={{
backgroundColor: 'blue',
width: Dimensions.get('screen').width,
height: Dimensions.get('screen').height,
}}>
<TouchableOpacity onPress={() => setShowModal(false)}>
<Feather name="menu" size={40} color="red" />
</TouchableOpacity>
</View>
</Modal>
You can use npm i react-native-modal to get your desired result.
<Modal
animationIn="slideInLeft"
animationOut="slideOutRight"
animationInTiming={500}
animationOutTiming={750}
isVisible={showModal}
useNativeDriver={true}
onBackButtonPress={() => {
setShowModal(!showModal);
}}>
<View
style={{
backgroundColor: 'blue',
width: Dimensions.get('screen').width,
height: Dimensions.get('screen').height,
}}>
<TouchableOpacity onPress={() => setShowModal(false)}>
<Feather name="menu" size={40} color="red" />
</TouchableOpacity>
</View>
</Modal>

React Native Flatlist ListHeaderComponent Doesn't Work

ListHeaderComponent inside flatlist doesn't work. It won't render nothing in header (above flatlist). If I however put some custom component it does work but it doesn't with my renderHeader function. I tried making a custom component with the same view as in renderHeader but when I used that nothing rendered so I don't know
My flatlist along with whole render:
render() {
const { height } = Dimensions.get("window");
return (
<View style={{flex: 1,
backgroundColor: "#EBECF4"}}>
{/* <Text>
Connection Status :{" "}
{this.state.connection_status ? "Connected" : "Disconnected"}
</Text> */}
{/* <Loader loading={this.state.loading} /> */}
<StatusBar backgroundColor="#63003d" barStyle="light-content" />
<SafeAreaView>
<ModernHeader
backgroundColor="#63003d"
height={50}
text="Eleph"
textStyle={{
color: "white",
fontFamily: "Lobster-Regular",
//fontWeight: "bold",
fontSize: 25,
}}
leftIconComponent={
<TouchableOpacity
style={{ marginRight: 0, margin: 0 }}
onPress={() =>
this.props.navigation.dispatch(DrawerActions.openDrawer())
}
>
<FontAwesome5 name="bars" size={22} color="white" />
</TouchableOpacity>
}
rightIconComponent={
<TouchableOpacity
style={{ marginLeft: 0, margin: 0 }}
onPress={() => this.props.navigation.navigate("Profile")}
>
{/* <MaterialCommunityIcons
name="chart-areaspline"
size={24}
color="#639dff"
/> */}
<Foundation name="graph-bar" size={24} color="white" />
{/* <FontAwesome name="bar-chart" size={24} color="white" /> */}
</TouchableOpacity>
}
/>
</SafeAreaView>
<FlatList
//contentInset={{ top: HEADER_HEIGHT }}
//contentOffset={{ y: -HEADER_HEIGHT }}
data={this.state.post}
extraData={this.state.post}
keyExtractor={(item) => item.id.toString()}
style={{
marginHorizontal: 0,
marginVertical: 6,
}}
renderItem={({ item }) => this.renderPost(item)}
ListFooterComponent={this.renderFooter}
ListHeaderComponent={this.renderHeader}
refreshControl={
<RefreshControl
style={{ color: "#639dff" }}
tintColor="#639dff"
titleColor="#fff"
refreshing={this.state.isLoading}
onRefresh={this.onRefresh}
/>
}
initialNumToRender={7}
onEndReachedThreshold={0.1}
showsVerticalScrollIndicator={false}
onEndReached={() => {
if (
!this.onEndReachedCalledDuringMomentum &&
!this.state.isMoreLoading
) {
this.getMore();
}
}}
onMomentumScrollBegin={() => {
this.onEndReachedCalledDuringMomentum = false;
}}
onScroll={(e) => {
scrollY.setValue(e.nativeEvent.contentOffset.y);
}}
></FlatList>
{/* <View style={styles.footer}>
<TouchableOpacity
activeOpacity={0.9}
onPress={this.getMore}
style={styles.loadMoreBtn}
>
<Text style={styles.btnText}>See more moods</Text>
{this.state.loading ? (
<ActivityIndicator color="white" style={{ marginLeft:8 }} />
) : null}
</TouchableOpacity>
</View> */}
</SafeAreaView>
</View>
My renderHeader function:
renderHeader = () => {
return (
<View
style={{
flex: 1,
flexDirection: "row",
backgroundColor: "#ffffff",
//width: "100%",
padding: 11,
alignItems: "center",
position: "absolute",
justifyContent: "center",
//top: 50,
//bottom: 0,
//left: 0,
//elevation: 4,
//right: 0,
//height: 50,
}}
//flexDirection: "row",
//backgroundColor: "#ffffff",
//width: "100%",
//padding: 11,
//alignItems: "center",
>
<TouchableOpacity
onPress={() => this.props.navigation.navigate("Post")}
>
<Text
style={{ alignItems: "center", color: "#C4C6CE" }}
//placeholder={How are you feeling right now ${this.state.user.name}?}
multiline
>{Tell us how are you feeling right now ${this.state.user.name}?}</Text>
</TouchableOpacity>
{/* <View style={styles.divider}></View> */}
</View>
);
}
Why for example renderFooter works??
renderFooter = () => {
if (!this.state.isMoreLoading) return true;
return (
<ActivityIndicator
size="large"
color={"#D83E64"}
style={{ marginBottom: 10 }}
/>
);
};
Use ListHeaderComponentStyle to style the ListHeaderComponent.
I created a simple snack for you, check if this helps. Your code looks okay but not sure about the whole screen design. Here is my snack link.
https://snack.expo.io/#saad-bashar/excited-fudge
It might be related to the other components inside your screen. So first check only with flatlist, remove all other components. Hope you can sort it out :)
The solution is to remove the "absolute" style in the header for flatlist. The question is mine im just answering with different account but this is the solution that worked.

React native react-native-google-places-autocomplete VirtualizedLists warning

I created a form in which I have a field called address. Where I implemented 'react-native-google-places-autocomplete' plugin. It's working fine if I don't add scrollView. But I need to add scrollView just because I have so many input fields inside that form. but then I got a warning "VirtualizedLists should never be nested inside plain ScrollViews with the same orientation".
Here is my code:
Add.js
<SafeAreaView style={{ flex: 1, paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0, backgroundColor: 'white' }}>
<View style={{ flex: 1 }}>
<ScrollView scrollEventThrottle={16}>
<View style={{ flex: 1 }}>
<Text style={{ fontSize: 20, marginTop: 5, marginBottom: 10, paddingHorizontal: 15, fontFamily: 'Mulish-SemiBold' }}>Add Ground</Text>
<TouchableWithoutFeedback style={styles.button} onPress={(e) => this.chooseFile()}>
<Image source={this.state.avatarSource ? this.state.avatarSource : require('./../../assets/images/default-cover.jpg')} style={{ width: '100%', height: 150 }} />
</TouchableWithoutFeedback>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Name</Text>
<TextInput
style={styles.input}
placeholder="e.g Drealit Stadium"
onChangeText={name => this.setState({ name })}
value={this.state.name}
autoCorrect={false}
/>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Address</Text>
{/*
onChangeText={address => this.setState({ address })}
value={this.state.address}
*/}
<ScrollView>
<GooglePlacesInput />
</ScrollView>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Contact Person Name</Text>
<TextInput
style={styles.input}
placeholder="e.g David Johnson"
onChangeText={organizer_name => this.setState({ organizer_name })}
value={this.state.organizer_name}
autoCorrect={false}
/>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Contact Person Number</Text>
<TextInputMask
type={'cel-phone'}
options={{
maskType: 'INTERNATIONAL',
}}
placeholder="e.g 509-962-9014"
style={styles.input}
value={this.state.organizer_number}
onChangeText={organizer_number => this.setState({ organizer_number })}
/>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Description</Text>
<TextInput
placeholder="e.g A Ground suitable for small side cricket tournament. Ideal for some fast paced cricket and lot of fun."
onChangeText={description => this.setState({ description })}
value={this.state.description}
autoCorrect={false}
multiline={true}
numberOfLines={4}
style={[styles.input, { height: 'auto', textAlignVertical: 'top' }]}
/>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Rate per hour / day</Text>
<TextInput
style={styles.input}
placeholder="e.g 3500"
keyboardType="numeric"
onChangeText={ratePerHourDay => this.setState({ ratePerHourDay })}
value={this.state.ratePerHourDay}
autoCorrect={false}
/>
</View>
<View style={styles.inputWrapper}>
<Text style={styles.inputLabel}>Rate per hour / night</Text>
<TextInput
style={styles.input}
placeholder="e.g 4500"
keyboardType="numeric"
onChangeText={ratePerHourNight => this.setState({ ratePerHourNight })}
value={this.state.ratePerHourNight}
autoCorrect={false}
/>
</View>
<View style={{ marginHorizontal: 15, marginVertical: 10 }}>
<TouchableWithoutFeedback style={styles.button} onPress={(e) => this.manageAddGround(e)}>
<LinearGradient
colors={["#4678f6", "#4475ee", "#5053eb"]}
start={{ x: 0, y: 0 }}
end={{ x: 0, y: 0 }}
locations={[0, 0.5, 0.6]}
style={styles.appButtonContainer}
>
<Text style={styles.buttonText}>Save</Text>
</LinearGradient>
</TouchableWithoutFeedback>
</View>
</View>
</ScrollView>
</View>
</SafeAreaView>
GooglePlacesInput.js
<View style={{ flex: 1 }}>
<GooglePlacesAutocomplete
placeholder='e.g 640 Cross Creek Dr, Ellensburg, WA, 98926'
query={{
key: GOOGLE_PLACES_API_KEY,
language: 'en',
}}
enablePoweredByContainer={false}
onPress={(data, details = null) => {
console.log("GooglePlacesInput -> data", data)
}}
debounce={200}
styles={{
textInputContainer: {
backgroundColor: '#fff',
borderTopWidth: 0,
borderBottomWidth: 0,
},
textInput: {
marginLeft: 0,
marginRight: 0,
height: 40,
borderBottomWidth: 1,
color: '#000',
borderBottomColor: '#dedede'
},
predefinedPlacesDescription: {
color: '#1faadb',
},
listView: {
backgroundColor: '#fff',
borderWidth: 0.5,
borderColor: '#dedede',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 6,
},
shadowOpacity: 0.05,
shadowRadius: 10,
elevation: 4
}
}}
/>
</View>
You are receiving this warning because react-native-google-places-autocomplete renders a component to show results, and you have wrapped in a .
It's a warning, not an error. If it works for you can leave it as is.

React Native Animation Swipe

How can I do this animation on React native?
I would like that when the user makes the gesture of sliding the helmet to the right, it moves to another screen and, when sliding the helmet to the left, it moves to another screen
is that simple?
Do you you have another recommendation for doing this?
Code Bellow:
const pan = useRef(new Animated.ValueXY()).current;
const panResponder = useRef(
PanResponder.create({
onMoveShouldSetPanResponder: () => true,
onPanResponderMove: Animated.event([null, {dx: pan.x, dy: pan.y}]),
onPanResponderRelease: () => {
Animated.spring(pan, {toValue: {x: 0, y: 0}}).start();
},
}),
).current;
return (
<View style={styles.container}>
<Text style={styles.title}>Nova corrida</Text>
<Text style={styles.description}>Percurso total de 2,7km</Text>
<Text style={styles.description}>Tempo estimado 10 minutos</Text>
<View style={styles.descriptionContainer}>
<Text style={styles.progressDescription}>
1,5km até coletar o pedido
</Text>
<Text style={styles.progressDescription}>McDonalds, 1002</Text>
<Text style={styles.progressDescription}>Rua das Oliveiras, 43</Text>
</View>
<View style={styles.progressBarContainer}>
<View
style={{
height: '100%',
flex: currentProgress,
backgroundColor: '#8CC63F',
}}
/>
<View
style={{
height: '100%',
flex: 100 - currentProgress,
backgroundColor: 'grey',
}}
/>
</View>
<Animated.View
style={{
transform: [{translateX: pan.x}, {translateY: pan.y}],
}}
{...panResponder.panHandlers}>
<View style={styles.box}>
<View style={styles.iconContainer}>
<MaterialCommunityIcons
style={styles.iconContainer}
name="racing-helmet"
size={36}
color="#fff"
/>
</View>
</View>
</Animated.View>
<View style={styles.iconsNavigation}>
<MaterialIcons
style={styles.iconSpace}
name="cancel"
size={30}
color="#707070"
/>
<MaterialIcons
style={styles.iconSpace}
name="check-circle"
size={30}
color="#8CC63F"
/>
</View>
</View>
);