react native searchbar overlapping mapview but cant zoom or pitch mapview - javascript

i managed to overlapped my searchbar over react native mapview, however with that i wont be able to pitch or zoom onto my map, are there any solution to this?
reason i wanted to add touchablewithoutfeedback over googleplacesautocomplete is due that googleplacesautocomplete will always prompt out virtual keyboard
return (
<Provider>
<MapView style={{
height: '100%',
width: '100%',
}}
ref={mapRef}
onMapReady={goToMyLocation}
initialRegion={location}
showsUserLocation={true}
showsMyLocationButton={true}
followsUserLocation={true}
scrollEnabled={true}
zoomEnabled={true}
pitchEnabled={true}
rotateEnabled={true}
showsTraffic={true}>
{location &&
<Marker
image={require ('../../assets/map_icon.png')}
title="You are here"
coordinate={location.coords} /> }
</MapView>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={{position: 'absolute', top: '5%', width: '100%', height: '100%'}}>
<GooglePlacesAutocomplete
placeholder="Search"
query={{
key: GOOGLE_PLACES_API_KEY,
language: 'en',
components: 'country:my'
}}
GooglePlacesDetailsQuery={{fields: 'geometry'}}
fetchDetails={true}
listViewDisplayed='auto'
autoFocus={false}
enableHighAccuracyLocation={true}
enablePoweredByContainer={false}
onPress={(data, details = null) => {
console.log('data:', data)
console.log('details:', details)
console.log(JSON.stringify(details?.geometry?.location))
}}
onFail={error => console.log(error)}
onNotFound={() => console.log('no results')}
textInputProps={{
autoFocus: true,
blurOnSubmit: false,
}}
isRowScrollable={true}
styles={{
textInput: {
height: 35,
width: '80%',
fontSize: 16,
borderRadius: 12,
borderColor: '#5A5A5A',
borderWidth: 1,
marginHorizontal: '3%',
backgroundColor: '#ECECEC',
},
predefinedPlacesDescription: {
color: '#1faadb'
},
container: {
marginHorizontal: '3%',
},
listView: {
borderRadius: 12,
elevation: 1,
},
row: {
backgroundColor: '#ECECEC',
height: 35,
paddingTop: 10,
}
}}
renderRightButton={() =>
<TouchableOpacity onPress={() => navigation.navigate('Profile')}>
<Image
style={{height: 35, width: 35, marginRight: '3%', borderRadius: 36}}
source={{uri: 'https://reactnative.dev/img/tiny_logo.png'}}
/>
</TouchableOpacity>}
/>
</View>
</TouchableWithoutFeedback>
<StatusBar style='auto' />
</Provider>
i tried wrapping mapview and view under touchablewithoutfeedback but that would result in react.children.only expected to receive single react.element.child
i also tried creating another view and wrapped mapview and googleplacesautocomplete in it then wrap that particular view in touchablewithoutfeedback, but still unable to zoom or pitch map
current view
based on the image attached, im not able to pitch or zoom into the map

I would try setting the height of the View element containing the GooglePlacesAutocomplete to a small fixed height like this:
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={{position: 'absolute', top: '5%', width: '100%', height: 65}}>
<GooglePlacesAutocomplete />
</View>
</TouchableWithoutFeedback>
Since the position of the View is set to absolute, its sitting on top of you MapView and not allowing you to interact with it properly. The only problem is now the encompassing View is set to a static height of 65 and when options become visible, they will drop out of view.
The GooglePlacesAutocomplete can be really tricky to overlay on a map because its position must be set to absolute in order to work on mobile. This means the height of the encompassing View will have to be toggled when the user is focused on the GooglePlacesAutocomplete.
Your final solution might look something like this (warning did not test):
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View
style={{
position: 'absolute',
top: '5%',
width: '100%',
height: this.state.autoCompleteFocused? "100%": 65
}}
>
<GooglePlacesAutocomplete
focus={()=>{this.setState({autoCompleteFocused: true})}
blur={()=>{this.setState({autoCompleteFocused: false})}
/>
</View>
</TouchableWithoutFeedback>

Related

React Native Text Input does not shrink in width after a certain amount on Web

So I have been building a Registration Page for my project, there are three InputTexts in a row, each inputtext has a flex:1 so that they fill up the screen accordingly. It works as intended on ipads, iphones and android devices but on web after shrinking the browser (like a phones width) the InputTexts just refuse to shrink any further.
I have included the screengrabs from the Browser(Current Behaviour on Web) and also from my ipad and android (Current and Intended Behaviour)
Browser (Current Behaviour On Web)
Ipad And Android(Current & Intended Behaviour)
Here is my Registration.js
.....More Code For Other Things
return (
<LinearGradient
colors={[colors.backgroundStart, colors.backgroundEnd]}
start={{ x: 0.5, y: 0.5 }}
style={styles.container}
>
<StatusBar translucent backgroundColor="transparent" />
<AppScreen>
<View style={styles.headingContainer}>
<Text style={styles.heading}>Lets Start</Text>
<Text style={styles.subHeading}>
Please Enter Your Details
</Text>
......More Code For Other Inputs
<View style={[styles.horizontalInputs, { marginTop: 30 }]}>
<Image source={profile} style={styles.iconStyle} />
<InputFields
placeholder="Department"
isPassword={false}
marginRight={15}
/>
<InputFields
placeholder="Semester"
isPassword={false}
maxLength={1}
input="numeric"
keyboardType="numeric"
marginRight={15}
/>
<InputFields
placeholder="Section"
isPassword={false}
maxLength={1}
/>
</View>
..............More Code For Buttons
</View>
</AppScreen>
</LinearGradient>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "flex-start",
alignItems: "flex-start",
},
headingContainer: {
marginHorizontal: "10%",
width: "80%",
marginTop: "10%",
},
heading: {
fontSize: 42,
fontWeight: "600",
color: colors.HeadingText,
},
subHeading: {
fontSize: 18,
fontWeight: "400",
color: colors.text,
marginTop: 5,
},
iconStyle: {
height: 48,
width: 38,
marginRight: 20,
},
horizontalInputs: {
height: 50,
flexDirection: "row",
},
});
Here is my InputFields.js
import React from "react";
import { StyleSheet, TextInput } from "react-native";
import colors from "../values/colors";
function InputFields(props) {
return (
<TextInput
style={[
styles.input,
{
marginLeft: props.marginLeft,
marginRight: props.marginRight,
marginTop: props.marginTop,
marginBottom: props.marginBottom,
},
]}
placeholder={props.placeholder}
autoCompleteType={props.Type}
autoComplete="off"
autoCorrect={false}
inputMode={props.input}
keyboardType={props.keyboardType}
secureTextEntry={props.isPassword}
maxLength={props.maxLength}
placeholderTextColor={colors.placeholderText}
contextMenuHidden={true}
onChangeText={props.onChangeText}
/>
);
}
const styles = StyleSheet.create({
input: {
height: 50,
borderBottomWidth: 3,
borderBottomColor: colors.InputBorder,
color: colors.text,
flex: 1,
outlineStyle: "none",
},
});
export default InputFields;
**I have only created this InputFields Component because I was just testing with flex flexBasis FlexShrink and Flexgrow, none of which work. **
It looks like the TextInput component has some kind of default width. You can fix this by adding width: "100%" to your input styles
const styles = StyleSheet.create({
input: {
height: 50,
borderBottomWidth: 3,
borderBottomColor: colors.InputBorder,
color: colors.text,
flex: 1,
outlineStyle: "none",
width: "100%",
},
});

Disable only horizontal scrolling in FlatList

How can I disable only horizontal scrolling on my FlatList? Putting it to false doesnt work. I want to be able to scroll it vertically but not horizontally.
<FlatList
data={data.me.friends.nodes}
//horizontal={false}
//scrollEnabled={false}
renderItem={({ item }) => (
<FriendItem friend={item} originatorId={data.me.id}/>
)}
keyExtractor={(item) => item.id.toString()}
ListEmptyComponent={NoFriendsContainer}
/>
FriendItem's return. FriendItem is the renderItem which is being used in the FlatList:
return (
<View style={styles.item}>
<TouchableOpacity
onPress={() =>
navigation.navigate('FriendDetails')
}>
<Thumbnail
style={styles.thumbnail}
source={{
uri:
'https://cdn4.iconfinder.com/person-512.png',
}}></Thumbnail>
</TouchableOpacity>
<View style={styles.nameContainer}>
<Text style={styles.userName}>{userName}</Text>
</View>
<View style={styles.deleteButtonContainer}>
<Button
rounded
style={styles.deleteButton}
onPress={() => onDeleteFriend(originatorId, friend.id)}>
<Icon name="trash-o" size={moderateScale(20)} color="black" />
</Button>
</View>
</View>
);
};
Styles:
export const styles = StyleSheet.create({
item: {
backgroundColor: 'white',
borderRadius: moderateScale(20),
padding: moderateScale(20),
marginVertical: moderateScale(8),
marginHorizontal: 16,
height: moderateScale(110),
width: moderateScale(360),
justifyContent: 'space-between',
flexDirection: 'row',
},
userName: {
paddingRight: 55,
paddingLeft: 10,
paddingTop: 20,
},
deleteButton: {
backgroundColor: '#31C283',
width: moderateScale(45),
justifyContent: 'center',
},
deleteButtonContainer: {
paddingTop: 12,
marginRight: 2,
},
thumbnail: {
height: 85,
width: 85,
marginLeft: 2,
paddingRight: 0,
position: 'relative',
},
nameContainer: {
flexDirection: 'row',
},
});
Edit:
When there are 4 items, it seems to be okay but as soon as another item is added to the list, the last item is disturbed and is overlapped with the footer? of the app.
It should actually be behind it so that we can scroll down and see the next items.
horizontal parameter is not related to horizontal scroll.
https://reactnative.dev/docs/flatlist#horizontal
If true, renders items next to each other horizontally instead of stacked vertically.
Your 'scroll issue' is your FriendItem , the issue is the width: moderateScale(360).
If you want your item be full width, with margin, you can just remove it.
Example with moderateScale(360)
Example removing width
item: {
backgroundColor: "white",
borderRadius: moderateScale(20),
padding: moderateScale(20),
marginVertical: moderateScale(8),
marginHorizontal: 16,
height: moderateScale(110),
justifyContent: "space-between",
flexDirection: "row",
}
Hope it helps you.
Regards,

Displaying line bellow TouchableOpacity options wrapped in a View at the border of parent

I have a menu like component in React Native, which is wrapped in a View. This View has 3 options. I would like each option to have a line below it almost touching border of the view.
In order to achieve this I have three TouchableOpacities with Text and a View, all wrap under the same parent. This is what my code looks like:
export function Menu () {
return (
<View style={{
flex: 1,
flexDirection: 'row',
backgroundColor: 'grey',
height: 50,
justifyContent: 'space-around',
alignContent: 'center',
alignItems: 'center'
}}>
<TouchableOpacity>
<Text>Option 1</Text>
<View
style={{
width: 50,
height: 4,
backgroundColor: 'red',
paddingTop: 0,
marginTop: 25,
marginBottom: 0
}}
/>
</TouchableOpacity>
<TouchableOpacity> <Text>Option 2</Text> </TouchableOpacity>
<TouchableOpacity> <Text>Option 3</Text> </TouchableOpacity>
</View>
)
}
The issue here is that by placing the inner View at the bottom through marginTop: 25, I push my text to the top of their parent, which I do not want. Here is the result of this code:
See how Option 2 and Option 3 are centered within their parent? That is exactly how I want Option 1 to be, but with the red line right on the edge of the grey box wrapping all three options.
How can this be achieved?
wrap the <Text> inside a a <View>. Its been quite some time since I last worked on RN but I think this code should give you the desired result.
<TouchableOpacity>
<View style={{flex: 1, alignItems: 'center', height: 46}}><Text>Option 1</Text></View>
<View
style={{
width: 50,
height: 4,
backgroundColor: 'red',
paddingTop: 0,
marginTop: 25,
marginBottom: 0
}}
/>
</TouchableOpacity>
PS: I think it should work even without the height: 46 for the <View> but I can't test it at the moment so can't assure.

How can we fliter data from header's TextInput on onChangeText in react native?

I have custom header which has TextInput for searching in StackNavigator.How can i get result on onChangeText of TextInput on particular class,
here is demo:
const StackNavigator = createStackNavigator({
TABS: {
screen: TabNav,
navigationOptions: ({ navigation }) => {
return {
header:
<View style={{ backgroundColor: '#025281', flexDirection:
'row', alignItems: 'center', height: 60 }}>
<TouchableOpacity
style={{ paddingLeft: 5 }}>
<Image source={require(back_arrowimg)} style={{
width: 25, height: 25, resizeMode: 'contain' }}/>
</TouchableOpacity>
<TextInput
style={{ color: 'white', paddingLeft: 15, }}
type='text'
placeholder={headerTitle}
onChangeText={this.loadUsers}
/>
</View>,
}
} },
[ConstFile.SCREEN_TITLES.WELCOME_SEARCH]: {
screen: WELCOMESEARCH,
navigationOptions: {
header: null
} }, } )
from navigationOption you can not do anything to other screen,
so what you can do is, move your header code into another file and use it as component in TabNav
something like this,
let say Header.js
<View style={{ backgroundColor: '#025281', flexDirection:
'row', alignItems: 'center', height: 60 }}>
<TouchableOpacity
style={{ paddingLeft: 5 }}>
<Image source={require(back_arrowimg)} style={{
width: 25, height: 25, resizeMode: 'contain' }}/>
</TouchableOpacity>
<TextInput
style={{ color: 'white', paddingLeft: 15, }}
type='text'
placeholder={headerTitle}
onChangeText={this.props.loadUsers} // see this change
/>
</View>
and in your TabNav.js use header as component,
<Header
loadUsers={(...your params)=>{
//do your necessary stuffs to display data in this file
}) />

How can I put an icon inside a TextInput in React Native?

I am thinking of having something like this https://android-arsenal.com/details/1/3941 where you have icon that you press to show password as plaintext, not as dots. However, I was unable to find any custom component that would help me.
I don't want to put too much time on such a minor feature, so I'm asking without having attempted anything yet: Is there a custom component I've missed? If not, is there a simple way to add children to TextInput? Or should I just have TextInput and Touchable side by side?
You can use combination of View, Icon and TextInput like so:
<View style={styles.searchSection}>
<Icon style={styles.searchIcon} name="ios-search" size={20} color="#000"/>
<TextInput
style={styles.input}
placeholder="User Nickname"
onChangeText={(searchString) => {this.setState({searchString})}}
underlineColorAndroid="transparent"
/>
</View>
and use flex-direction for styling
searchSection: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
searchIcon: {
padding: 10,
},
input: {
flex: 1,
paddingTop: 10,
paddingRight: 10,
paddingBottom: 10,
paddingLeft: 0,
backgroundColor: '#fff',
color: '#424242',
},
Icons were taken from "react-native-vector-icons"
Basically you can’t put an icon inside of a textInput but you can fake it by wrapping it inside a view and setting up some simple styling rules.
Here's how it works:
put both Icon and TextInput inside a parent View
set flexDirection of the parent to ‘row’ which will align the
children next to each other
give TextInput flex 1 so it takes the full width of the parent View
give parent View a borderBottomWidth and push this border down with paddingBottom (this will make it appear like a regular textInput with a borderBottom)
(or you can add any other style depending on how you want it to look)
Code:
<View style={styles.passwordContainer}>
<TextInput
style={styles.inputStyle}
autoCorrect={false}
secureTextEntry
placeholder="Password"
value={this.state.password}
onChangeText={this.onPasswordEntry}
/>
<Icon
name='what_ever_icon_you_want'
color='#000'
size={14}
/>
</View>
Style:
passwordContainer: {
flexDirection: 'row',
borderBottomWidth: 1,
borderColor: '#000',
paddingBottom: 10,
},
inputStyle: {
flex: 1,
},
(Note: the icon is underneath the TextInput so it appears on the far right, if it was above TextInput it would appear on the left.)
This is working for me in ReactNative 0.60.4
View
<View style={styles.SectionStyle}>
<Image
source={require('../assets/images/ico-email.png')} //Change your icon image here
style={styles.ImageStyle}
/>
<TextInput
style={{ flex: 1 }}
placeholder="Enter Your Name Here"
underlineColorAndroid="transparent"
/>
</View>
Styles
SectionStyle: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
borderWidth: 0.5,
borderColor: '#000',
height: 40,
borderRadius: 5,
margin: 10,
},
ImageStyle: {
padding: 10,
margin: 5,
height: 25,
width: 25,
resizeMode: 'stretch',
alignItems: 'center',
}
In case is useful I share what I find a clean solution:
<View style={styles.inputContainer}>
<TextInput
style={styles.input}
onChangeText={(text) => onChange(text)}
value={value}
/>
<Icon style={styles.icon} name="your-icon" size={20} />
</View>
and then in your css
inputContainer: {
justifyContent: 'center',
},
input: {
height: 50,
},
icon: {
position: 'absolute',
right: 10,
}
import { TextInput } from 'react-native-paper';
<TextInput
label="Password"
secureTextEntry
right={<TextInput.Icon name="eye" />}
/>
You can use this module which is easy to use: https://github.com/halilb/react-native-textinput-effects
You can wrap your TextInput in View.
<View>
<TextInput/>
<Icon/>
<View>
and dynamically calculate width, if you want add an icon,
iconWidth = 0.05*viewWidth
textInputWidth = 0.95*viewWidth
otherwise textInputwWidth = viewWidth.
View and TextInput background color are both white. (Small hack)
//This is an example code to show Image Icon in TextInput//
import React, { Component } from 'react';
//import react in our code.
import { StyleSheet, View, TextInput, Image } from 'react-native';
//import all the components we are going to use.
export default class App extends Component<{}> {
render() {
return (
<View style={styles.container}>
<View style={styles.SectionStyle}>
<Image
//We are showing the Image from online
source={{uri:'http://aboutreact.com/wp-content/uploads/2018/08/user.png',}}
//You can also show the image from you project directory like below
//source={require('./Images/user.png')}
//Image Style
style={styles.ImageStyle}
/>
<TextInput
style={{ flex: 1 }}
placeholder="Enter Your Name Here"
underlineColorAndroid="transparent"
/>
</View>
<View style={styles.SectionStyle}>
<Image
//We are showing the Image from online
source={{uri:'http://aboutreact.com/wp-content/uploads/2018/08/phone.png',}}
//You can also show the image from you project directory like below
//source={require('./Images/phone.png')}
//Image Style
style={styles.ImageStyle}
/>
<TextInput
style={{ flex: 1 }}
placeholder="Enter Your Mobile No Here"
underlineColorAndroid="transparent"
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
margin: 10,
},
SectionStyle: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
borderWidth: 0.5,
borderColor: '#000',
height: 40,
borderRadius: 5,
margin: 10,
},
ImageStyle: {
padding: 10,
margin: 5,
height: 25,
width: 25,
resizeMode: 'stretch',
alignItems: 'center',
},
});
Expo
Anyone who's struggling on this
you can try to follow mine also
<View style={{flex:1}}>
<KeyboardAvoidingView enabled>
<View style={{flexDirection:'row',paddingBottom:5, borderColor:'#ccc',borderBottomWidth:1}}>
<TextInput
style={{flex:1}}
onChangeText={(UserEmail) => setUserEmail(userEmail)}
placeholder="Password"
placeholderTextColor="#ccc"
autoCapitalize="none"
keyboardType="default"
returnKeyType="next"
ref={passwordInputRef}
onSubmitEditing={Keyboard.dismiss}
blurOnSubmit={false}
/>
<FontAwesome5 name={"eye"} size={25} style={{alignSelf:'center'}}/>
</View>
</KeyboardAvoidingView>
</View>
Here you have an example I took from my own project, i have just removed what i thought we didnt need for the example.
import React, { Component } from 'react';
import {
Text,
TouchableOpacity,
View,
StyleSheet,
Dimensions,
Image
} from 'react-native';
class YourComponent extends Component {
constructor(props) {
super(props);
this._makeYourEffectHere = this._makeYourEffectHere.bind(this);
this.state = {
showPassword: false,
image: '../statics/showingPassImage.png'
}
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity style={styles.button} onPress={this._makeYourEffectHere}>
<Text>button</Text>
<Image style={styles.image} source={require(this.state.image)}></Image>
</TouchableOpacity>
<TextInput password={this.state.showPassword} style={styles.input} value="abc" />
</View>
);
}
_makeYourEffectHere() {
var png = this.state.showPassword ? '../statics/showingPassImage.png' : '../statics/hidingPassImage.png';
this.setState({showPassword: !this.state.showPassword, image: png});
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
justifyContent: 'center',
flexDirection: 'column',
alignItems: 'center',
},
button: {
width: Dimensions.get('window').width * 0.94,
height: 40,
backgroundColor: '#3b5998',
marginTop: Dimensions.get('window').width * 0.03,
justifyContent: 'center',
borderRadius: Dimensions.get('window').width * 0.012
},
image: {
width: 25,
height: 25,
position: 'absolute',
left: 7,
bottom: 7
},
input: {
width: Dimensions.get('window').width * 0.94,
height: 30
}
});
module.exports = YourComponent;
I hope It helps you.
Let me know if it was useful.
you can also do something more specific like that based on Anthony Artemiew's response:
<View style={globalStyles.searchSection}>
<TextInput
style={globalStyles.input}
placeholder="Rechercher"
onChangeText={(searchString) =>
{this.setState({searchString})}}
underlineColorAndroid="transparent"
/>
<Ionicons onPress={()=>console.log('Recherche en cours...')} style={globalStyles.searchIcon} name="ios-search" size={30} color="#1764A5"/>
</View>
Style:
searchSection: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
borderRadius:50,
marginLeft:35,
width:340,
height:40,
margin:25
},
searchIcon: {
padding: 10,
},
input: {
flex: 1,
paddingTop: 10,
paddingRight: 10,
paddingBottom: 10,
paddingLeft: 0,
marginLeft:10,
borderTopLeftRadius:50,
borderBottomLeftRadius:50,
backgroundColor: '#fff',
color: '#424242',
},
It's now more easier to use with nativebase input hope this will help someone. I used Iconscout and you can use any icon library.
<View style={styles.input}>
<Input leftElement={<UilReact size="30" color="#61DAFB" style={styles.icon}/>} style={styles.input} size={'2xl'} variant="underlined" placeholder="Round" />
</View>
const styles = StyleSheet.create({
input: {
justifyContent:'center'
},
icon: {
marginRight:10
}
});
You can test this too, dont forget to add the style below as well.
<View style={styles.searchContainerStyle}>
<Ionicons name="search" size={24} color="gray"/>
<View style={{ flex: 1 }}>
<TextInput
type="search"
placeholder="Search for doctors & labs"
style={{ marginLeft: Sizes.fixPadding}}
/>
</View>
</View>
searchContainerStyle: {
backgroundColor: "#F5F5F5",
borderRadius: 30.0,
height: 45.0,
flexDirection: "row",
alignItems: "center",
paddingLeft: Sizes.fixPadding + 5.0,
marginBottom: 10,
},
if you are Willing to ADD Your OWN Custome SVG to the Left of Right.
Follow this..
Import svgs from "your Svgs Location"
<TextInputRNP
label="lable"
placeholder="placeholder"
right={<TextInput.Icon icon={() => <svgs.Calender />} size={30} />}
left={<TextInput.Icon icon={() => <svgs.Calender2 />} size={30} />}
/>
Here TextInputRNP is the text Input from React-native-Paper

Categories

Resources