Why is scrollToEnd() not working on Android? - reactjs

I currently have it set such that when the user opens the keyboard it scrolls to the bottom when the scroll view shrinks.
<ScrollView
contentContainerStyle={{ flexGrow: 1 }}
ref={(ref) => (this.scrollView = ref)}
>
<TextInput
onFocus = {this.scrollDown}
/>
scrollDown = () => {
this.scrollView.scrollToEnd();
}
This works on IOS perfectly fine, but doesn't seem to be working on Android.
Android:
https://imgur.com/a/9HfaCMd
iOS:
https://imgur.com/a/dB1WeoW

--Update--
After looking your record, it doesn't seems caused by scrollToEnd.
What you need may be KeyboardAvoidingView
It can automatically adjust either its height, position, or bottom padding based on the keyboard height.
const keyboardVerticalOffset = Platform.OS === 'ios' ? 40 : 0 //update 2 something like this
...
<KeyboardAvoidingView
behavior='position' //update 2
keyboardVerticalOffset={keyboardVerticalOffset} //update 2
style={styles.container}
>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.inner}>
<Text style={styles.header}>Header</Text>
<TextInput placeholder="Username" style={styles.textInput} />
<View style={styles.btnContainer}>
<Button title="Submit" onPress={() => null} />
</View>
</View>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>

Related

Dropdown picker placed above ScrollView isn't responding to scroll but ScrollView is

I have placed a Dropdown picker above a ScrollView, when both Dropdown picker and ScrollView is poppulated with data and I'm trying to scroll through the data in Dropdown it instead scrolling the ScrollView in the background.
Infact the Dropdown isn't scrolling at all, even if there's no ScrollView in the background, I'm not sure what I'm doing wrong.
<View style={styles.lowerContainer}>
{sevaListDrop ? (
<>
<View // specific search section
style={[styles.searchContainer, {zIndex: 2, marginBottom: '2%'}]}>
<DropDownPicker // dropdown
style={{borderColor: '#ccc'}}
containerStyle={{flex: 3, marginLeft: '2%'}}
dropDownContainerStyle={{
borderColor: '#ccc',
zIndex: 1000,
elevation: 1000,
position: 'absolute',
}}
open={openDrop}
setOpen={setOpenDrop}
items={sevaListDrop?.map(item => ({
label: item.sevaName,
value: item.calendarId,
}))}
placeholder="Select Seva"
value={calendarId}
setValue={type => setCalendarId(type)}
/>
<PrimaryButton // search button
name="Search"
action={search}
/>
</View>
<View // lower container for seva list
style={[styles.lowerContainer, {justifyContent: 'center'}]}>
{sevaList ? (
<ScrollView // seva list
style={{width: '100%'}}
contentContainerStyle={{
alignItems: 'center',
paddingBottom: 50,
}}
showsVerticalScrollIndicator={false}>
{sevaList?.map((item, index) => (
<SevaCard // seva card
key={index}
sevakName={item.sevakName}
bookedBy={item.bookedBy}
noOfAttendees={item.noOfAttendees}
onChangeText={text => {
setPeopleCount(item.slotId, text);
}}
onPress={() =>
updateAttendees(item.slotId, item.calendarId)
}
/>
))}
</ScrollView>
) : noDataInner ? (
<CautionSection // no data container
title="No Data Found"
icon="no_user_found"
/>
) : (
<CautionSection // default container
title="Search Patron Id"
icon="search"
/>
)}
</View>
</>
) : (
<View // lower caution container
style={[styles.lowerContainer, {justifyContent: 'center'}]}>
{noData ? (
<CautionSection // no data container
title="No Data Found"
icon="no_user_found"
/>
) : noConnection ? (
<CautionSection // no connection container
title="No Connection"
icon="no_connection"
/>
) : (
<CautionSection // default container
title="Search Patron Id"
icon="search"
/>
)}
</View>
)}
</View>
What is really causing this problem is the zIndex:2 in the <View> // specific search section. If you erase that zIndex you should stop having this problem.
At the same time, you may have a problem with your Dropdown, because you will not see the options anymore (or the Dropdown itself). To solve this you should have your <View // lower container for seva list component inside your <View // specific search section component, and then add a zIndex:0 in that last <View> like this:
<View> // specific search section
<DropdownPicker zIndex={1000}></DropdownPicker>
<PrimaryButton></PrimaryButton>
<View style={{zIndex:0}}>
<ScrollView>
<SevaCard></SevaCard>
</ScrollView>
</View>
</View>
As you can see, I also added a zIndex as an attribute of the element, since it is allowed in DropdownPicker, and preferred.

Prevent Item Background Color From Changing Flatlist

I have a FlatList that is pulling in contact from a user's phone. I want to give each contact that doesn't have an avatar a random color from an array of hex color codes which I call "CircleColors".
This is what I'm trying:
<FlatList
data={filteredContacts}
renderItem={({ item }) => (
<View key={uuidv4()} style={styles.contactItem}>
<View style={item.avatar && styles.contactAvatar}>
{item.avatar && (
<Image
style={{
borderRadius: 50,
width: 50,
height: 50,
}}
source={{
uri: item.avatar,
}}
/>
)}
{!item.avatar && (
<ContactItem
itemData={item.name}
color={
CircleColors[
Math.floor(Math.random() * CircleColors.length)
]
}
/>
)}
</View>
<View>
<Text style={styles.contactTxt}>{`${item.name}`}</Text>
<Text
style={
item.usernames.length
? styles.contactUser
: styles.noUser
}
>
{item.usernames.length ? `$${item.usernames}` : null}
</Text>
</View>
</View>
)}
/>
And here is the code for the contact item:
const ContactItem = ({ itemData, color }) => {
return (
<View
style={[
styles.userCircle,
{
backgroundColor: color,
},
]}
>
<Text style={styles.userCircleTxt}>
{itemData.substr(0, 1).toUpperCase()}
</Text>
</View>
);
};
The problem is that on scroll, the flatlist rerenders each item, and the colors change each time. Is there a way to persist the original random color given to each item background, even on scroll?
Any help would be greatly appreciated.
Thanks!
the problem come with this line
<View key={uuidv4()} style={styles.contactItem}>
the key always change, you should pass index to key
renderItem={({ item,index }) => (
<View key={index} style={styles.contactItem}>
Pass key as index and dynamic background color styles in array like below -
renderItem={({ item,index }) => (
<View key={index} style={[{item.background},styles.contactItem]}>

Buttons on top of TextInput Element is not working

I am trying to make visible list of buttons on top of a multi-line text input, which is now working. But when i am clicking on one of these button nothing is happening.
I am using zIndex to bring the childComponent on top of TextInput, Now when i am clicking on these button TextInput is getting focus instead of triggering button click event.
I just started learning react-native so I am not able to understand where i need to make the changes for making it functional.
Sample Code structure given below:*
const Component_1=()=>{
const UpdateTextInput=(ip,callType)=>{
console.log(ip);
}
return (<View keyboardShouldPersistTaps={'handle'}>
<View style={{flexDirection:'row',backgroundColor:'#fff',zIndex:10}}>
<ChildComponent callBackFunc={(ip,callType)=>UpdateTextInput(ip,callType)} />
</View>
<View>
<TextInput
multiline
onChangeText={(text)=>updateString(text,'')}
/>
</View>
</View>
)
}
export default Component_1;
const ChildComponent=({callBackFunc})=>{
const [ButtonSection,SetButtonSection]=useState(false)
return (
<View style={{flexDirection:'row-reverse'}}>
<View style={{flexDirection:'column',width:'15%',position:'absolute'}} >
<TouchableOpacity onPress={()=>SetButtonSection(!ButtonSection)} style={{borderColor:'tomato',borderEndWidth:1}}>
<Icon
name='arrow-drop-down'
size={25}
type='material'
iconStyle={{color:'tomato',textAlign:'center',paddingHorizontal:20,paddingVertical:8,fontSize:20}}
/>
</TouchableOpacity>
{ButtonSection==true
?<View style={{flexDirection:'column',position:'relative',backgroundColor:'#ccc'}}>
<TouchableOpacity onPress={()=>callBackFunc('','CLR')} style={{borderColor:'tomato',borderEndWidth:1}}>
<Icon
name='block'
size={25}
type='material'
iconStyle={{color:'tomato',textAlign:'center',paddingHorizontal:10,paddingVertical:8,fontSize:20}}
/>
</TouchableOpacity>
<TouchableOpacity onPress={()=>callBackFunc('','COPY')} style={{borderColor:'tomato',borderEndWidth:1}}>
<Icon
name='content-copy'
size={25}
type='material'
iconStyle={{color:'tomato',textAlign:'center',paddingHorizontal:10,paddingVertical:8,fontSize:20}}
/>
</TouchableOpacity>
<TouchableOpacity onPress={()=>callBackFunc('','SAVE')} style={{borderColor:'tomato',borderEndWidth:1}}>
<Icon
name='save'
size={25}
type='material'
iconStyle={{color:'tomato',textAlign:'center',paddingHorizontal:10,paddingVertical:8,fontSize:20}}
/>
</TouchableOpacity>
<Button title='BTN' onPress={()=>console.log('Button1')
}/>
</View>
:null
}
</View>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false} keyboardShouldPersistTaps={'handle'} style={{marginRight:50}}>
<Item/>
</ScrollView>
</View>
)
}
export default ChildComponent
Instead of using zIndex, use absolute position in view.
position: 'absolute'
Give absolute position to the view of child component

React Native two taps required for onPress to work

I have created an autoconplete search field which displays the places using mapbox API. I am using the ListView for sugesstions list. when list appears and I tap on the address i need to select, on the first tap keyboard hides and onPress works in the second tap.
I am trying to figure out what's wrong.
<View style={styles.container}>
<View style={styles.searchContainer}>
<View style={styles.mapMarkerContainer}>
{mapMarkerIcon}
</View>
<View style={styles.inputContainer}>
<TextInput
style={styles.textinput}
onChangeText={this.searchLocation}
placeholder="Type your address here"
underlineColorAndroid='rgba(0,0,0,0)'
value={this.state.inputVal}
placeholderTextColor="#fff"
/>
</View>
</View>
<View keyboardShouldPersistTaps='always' style={styles.listViewContainer}>
<ListView
dataSource={ds.cloneWithRows(this.state.searchedAdresses)}
renderRow={this.renderAdress}
style={styles.listView}
renderSeparator={this.renderSeparator}
enableEmptySections
/>
</View>
</View>
renderAddress
renderAdress = (address) => {
return (
<TouchableOpacity onPress={() => this.onListItemClicked(address)} style={styles.listItem}>
<View>
<Text>{address.place_name}</Text>
</View>
</TouchableOpacity>
);
};
onListItemClicked
onListItemClicked= (address) => {
this.props.onAddressGet(address);
console.log(address);
this.setState({
searchedAdresses: [],
inputVal: address.place_name
});
}
You should move the keyboardShouldPersistTaps-property to the ListView as it is a property from ScrollView and will be inherited to ListView:
Instead of
<View keyboardShouldPersistTaps='always'
<ScrollView ...>
You need:
<View
<ScrollView keyboardShouldPersistTaps='always' ...>
https://facebook.github.io/react-native/docs/scrollview.html#keyboardshouldpersisttaps

react-native-maps other Markers visible on Tooltip - iOS

On iOS Markers are Visible on Tooltip. I think Tooltip should be always on the top. Did I missed something, or it is a popular issue in react-native-maps ?
<_MapView
style={[{flex: 1}, this.props.style]}
showsPointsOfInterest={true}
region={region}
{...this.props}
>
{annotations.map((marker, ind) => (
<_MapView.Marker
key={ind}
image={marker.image}
coordinate={marker.latlng}
ref={ref => { this.markers[ind] = ref }}
onPress={() => {
if (this.activeMarker) {
this.activeMarker.closeCallout()
}
this.markers[ind].showCallout()
}}
>
<_MapView.Callout style={StyleSheet.mapView.callOut} onPress={marker.rightCalloutView}>
<TouchableHighlight
underlayColor="transparent"
>
<View style={StyleSheet.mapView.toolTip}>
<Text>{marker.title}</Text>
<View>
<Icon name="chevronRight" />
</View>
</View>
</TouchableHighlight>
</_MapView.Callout>
</_MapView.Marker>
))}
</_MapView>

Resources