horizontal scroll view is not working in my react native app. Here is my code below:
return (
<View style={styles.container}>
{loading ? (
<ActivityIndicator size="large" color={COLORS.blue} />
) : (
kioskData.map((item, index) => {
return (
<View key={index} style={styles.container1}>
<ScrollView
horizontal={true}
showsHorizontalScrollIndicator={false}>
<>
<Text>{item.product_price}</Text>
<Text>{item.product_name}</Text>
</>
</ScrollView>
</View>
);
})
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
color: COLORS.black,
backgroundColor: COLORS.white,
},
container1: {
flex: 1,
},
});
Am not sure where I am going wrong. Thanks for your help in advance.
The issue is with the usage of ScrollView in the wrong area which is inside of the loop (map).
Instead of creating an independent ScrollView for each item in the list, We can wrap the List Text elements within one single ScrollView Component.
let's update the ScrollView component tree to fix up the issue,
<View style={styles.container}>
{loading ? (
<ActivityIndicator size="large" color={COLORS.blue} />
) : (
<View style={styles.container1}>
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
{kioskData.map((item, index) => {
return (
<Fragment key={index}>
<Text>{item.product_price}</Text>
<Text>{item.product_name}</Text>
</Fragment>
);
})}
</ScrollView>
</View>
)}
</View>
Additional Tip:
If the list is quite large and has some performance concerns you can go for FlatList component for the same UI implementation.
const renderItem = ({item}) => (
<>
<Text>{item.product_price}</Text>
<Text>{item.product_name}</Text>
</>
);
return (
<View style={styles.container}>
{loading ? (
<ActivityIndicator size="large" color={COLORS.blue} />
) : (
<View style={styles.container1}>
<FlatList
data={kioskData}
horizontal
showsHorizontalScrollIndicator={false}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</View>
)}
</View>
);
<View style={{flexDirection: 'row'}}>
<ScrollView
horizontal={true}
showsHorizontalScrollIndicator={false}>
<Text>asdasdasd</Text>
<Text>asdasdasd</Text>
<Text>asdasdasd</Text>
<Text>asdasdasd</Text>
<Text>asdasdasd</Text>
<Text>asdasdasd</Text>
<Text>asdasdasd</Text>
<Text>asdasdasd</Text>
<Text>asdasdasd</Text>
<Text>asdasdasd</Text>
</ScrollView>
</View>
Related
I was messing with my code and suddenly the ScrollView decided to disappear.
For some reason, the ScrollView works "properly" inside the Character bar View
but when it is inside of the base View it just isn't there.
export default class CharacterSheet extends Component {
render() {
return (
<View style={{flex:1}}>
<View style={styles.TopBar}>
<View>
</View>
</View>
<View style={{flex:1}}>
<View style={styles.CharacterBar}>
</View><View style={styles.Base}>
<ScrollView style={styles.scroll}>
<View style={{paddingTop:72}}>
<View style={styles.spellsBox}>
<Text>Hi</Text>
</View>
<View style={styles.spellsBox}>
<Text>e</Text>
</View>
<View style={styles.spellsBox}>
<Text>a</Text>
</View>
<View style={styles.spellsBox}>
<Text>Hi</Text>
</View>
<View style={styles.spellsBox}>
<Text>Hi</Text>
</View>
<View style={styles.spellsBox}>
<Text>Hi</Text>
</View>
</View>
</ScrollView>
</View>
<Animated.View style={styles.CharacterStatsBar}>
</Animated.View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
CharacterBar:{
height:72,
backgroundColor:'#242527'
},
CharacterStatsBar:{
position:'absolute',
top: 72,
left: 0,
right: 0,
height:72,
backgroundColor:'#404040',
borderBottomWidth:2,
borderBottomColor:'#c53131',
borderTopWidth:1,
borderTopColor:'#838383',
},
Base:{
flex:1,
backgroundColor:'#fff',
},
scroll:{
width:'95%',
alignSelf:'center'
},
spellsBox:{
height:80,
marginTop:10,
paddingVertical:10,
borderColor:'#777',
borderWidth:3,
justifyContent:'center'
}
});
I'm trying to run this in an android device
this problem is pretty annoying and is stressing me a little bit.
Try Like this , don't wrap ScrollView inside multiple Views.
<View style={{flex:1}}>
<View style={styles.TopBar}>
<View>
</View>
</View>
<ScrollView style={styles.scroll}>
<View style={{paddingTop:72}}>
<View style={styles.spellsBox}>
<Text>Hi</Text>
</View>
<View style={styles.spellsBox}>
<Text>e</Text>
</View>
<View style={styles.spellsBox}>
<Text>a</Text>
</View>
<View style={styles.spellsBox}>
<Text>Hi</Text>
</View>
<View style={styles.spellsBox}>
<Text>Hi</Text>
</View>
<View style={styles.spellsBox}>
<Text>byee</Text>
</View>
</View>
</ScrollView>
</View>
My FlatList triggers onendreached not as expected. onEndReached gets called again and again. I have read some suggestion to wrap flatlist in a view with flex:1 but I still doesn't work properly. Also removing the scrollView didn't work-
This didn't help https://github.com/GeekyAnts/NativeBase/issues/1736#issuecomment-401815949
<View style={baseStyles.body}>
<View style={{flexDirection:"row", backgroundColor:theme.button.tertiary}}>
<View style={{flex:1}}>
<SearchBar
onChangeText={(query) => this.setState({query})}
placeholder='Hier suchen...'
showLoading
/>
</View>
</View>
<View style={{flex:1}}>
<ScrollView style={{flex: 1, flexDirection:'column'}}>
<View style={{flex:1}}>
<FlatList
data={articlesData}
renderItem={renderFunction}
onEndReached={this._onEndReached}
onEndThreshold={0}
refreshing={this.state.isLoading}
onRefresh={this.onRefresh}
keyExtractor={item => item.slug}
/>
</View>
<View style={{marginBottom:10}}>
<Text style={{color:this.state.theme.text.primary,textAlign:"center",fontSize:16}}>Gefunden: {rowCount}</Text>
</View>
</ScrollView>
</View>
</View>
If it is loading or error you can try to use onEndReached={this.state.isLoading ? () => {} : this._onEndReached}; just let onEndReached do nothing when the state is loading. I've tried serveral way (debounce, await setState, using flag) but only this way work as expected.
<View style={baseStyles.body}>
<View style={{flexDirection:"row", backgroundColor:theme.button.tertiary}}>
<View style={{flex:1}}>
<SearchBar
onChangeText={(query) => this.setState({query})}
placeholder='Hier suchen...'
showLoading
/>
</View>
</View>
<View style={{flex:1}}>
<ScrollView style={{flex: 1, flexDirection:'column'}}>
<View style={{flex:1}}>
<FlatList
data={articlesData}
renderItem={renderFunction}
onEndReached={this.state.isLoading ? () => {} : this._onEndReached}
onEndThreshold={0}
refreshing={this.state.isLoading}
onRefresh={this.onRefresh}
keyExtractor={item => item.slug}
/>
</View>
<View style={{marginBottom:10}}>
<Text style={{color:this.state.theme.text.primary,textAlign:"center",fontSize:16}}>Gefunden: {rowCount}</Text>
</View>
</ScrollView>
</View>
</View>
I am new in react native and I need to show and hide for text input on each comment reply option.How to unique each and every section so I can hide and show text input for each button click.
Here is my flat list:
<FlatList
data={item.comments}
keyExtractor={this._keyExtractor}
renderItem={this.renderRowItem}
extraData={this.state}
/>
Here is render row item:
renderRowItem = (itemData) => {
Moment.locale('en');
return (
<View style={styles.commentSection}>
<View style={{flexDirection:'row'}}>
<View style={{flex:1,flexDirection:'row'}}>
<Image style={{ height: 30,width: 30,borderRadius: 15, marginTop:8}}
source={{ uri: this.state.profile_image }} resizeMode='cover' />
<View style={{width:width,paddingHorizontal:10,paddingRight:10,borderBottomColor:'#D2D0D1',borderBottomWidth:1,paddingBottom:10}}>
<View style={{flexDirection:'row',paddingTop:5}}>
<Text style={{fontWeight:'600',fontSize:14}}>
{itemData.item.firstName} {itemData.item.surname}</Text>
<Text style={{color:'grey',fontWeight:'500',fontSize:12,paddingHorizontal:20}}>
{Moment(itemData.item.dateCreated).format('d MMM YYYY')}</Text>
</View>
<Text style={{fontWeight:'500',color:'grey',marginTop:5}}>
{itemData.item.comment}</Text>
<Text onPress={this.ShowHideTextComponentView} style={{width:width*0.8,color:"#F766FF",textAlign:'right',alignSelf:'stretch',fontSize:12,fontWeight:'600'}}>
Reply</Text>
<View>
<FlatList
data={itemData.item.replies}
keyExtractor={this._keyExtractor}
renderItem={this.renderRowReply}
/>
</View>
<View>
{
this.state.replyboxShow ?
<View style={{flex:1,flexDirection:'row',width:width*0.6,marginLeft:10}}>
<TextInput
style = {[styles.inputReplyBox,
!this.state.postValidate ? styles.error : null]}
placeholder="Enter message here"
placeholderTextColor="grey"
onChangeText = {reply => this.setState({reply})}
/>
<TouchableOpacity style={{position: 'absolute',right:6,top:5,alignSelf:'stretch'}}
onPress={() => this.replyCom(itemData.item._id)}>
<Icon name="paper-plane-o" size={20} color="#F766FF" />
</TouchableOpacity>
</View>
: null
}
</View>
</View>
</View>
</View>
</View>
)
}
In the end of render item I am using reply button and on click I want to show and hide each text input fields:
This is design I need to implement.
My ShowHideTextComponentView function:
ShowHideTextComponentView = () =>{
if(this.state.replyboxShow == true){
this.setState({replyboxShow: false})
}else{
this.setState({replyboxShow: true})
}
}
With your replyboxShow state, all the item will be showing or hiding,
i create a replyboxShowId state to save the item_id of the element
you want to show.
renderRowItem = (itemData) => {
Moment.locale('en');
return (
<View style={styles.commentSection}>
<View style={{flexDirection:'row'}}>
<View style={{flex:1,flexDirection:'row'}}>
<Image style={{ height: 30,width: 30,borderRadius: 15, marginTop:8}}
source={{ uri: this.state.profile_image }} resizeMode='cover' />
<View style={{width:width,paddingHorizontal:10,paddingRight:10,borderBottomColor:'#D2D0D1',borderBottomWidth:1,paddingBottom:10}}>
<View style={{flexDirection:'row',paddingTop:5}}>
<Text style={{fontWeight:'600',fontSize:14}}>
{itemData.item.firstName} {itemData.item.surname}</Text>
<Text style={{color:'grey',fontWeight:'500',fontSize:12,paddingHorizontal:20}}>
{Moment(itemData.item.dateCreated).format('d MMM YYYY')}</Text>
</View>
<Text style={{fontWeight:'500',color:'grey',marginTop:5}}>
{itemData.item.comment}</Text>
<Text onPress={this.ShowHideTextComponentView.bind(this,itemData.item._id)} style={{width:width*0.8,color:"#F766FF",textAlign:'right',alignSelf:'stretch',fontSize:12,fontWeight:'600'}}>
Reply</Text>
<View>
<FlatList
data={itemData.item.replies}
keyExtractor={this._keyExtractor}
renderItem={this.renderRowReply}
/>
</View>
<View>
{
this.state.replyBoxShowId === itemData.item._id ?
<View style={{flex:1,flexDirection:'row',width:width*0.6,marginLeft:10}}>
<TextInput
style = {[styles.inputReplyBox,
!this.state.postValidate ? styles.error : null]}
placeholder="Enter message here"
placeholderTextColor="grey"
onChangeText = {reply => this.setState({reply})}
/>
<TouchableOpacity style={{position: 'absolute',right:6,top:5,alignSelf:'stretch'}}
onPress={() => this.replyCom(itemData.item._id)}>
<Icon name="paper-plane-o" size={20} color="#F766FF" />
</TouchableOpacity>
</View>
: null
}
</View>
</View>
</View>
</View>
</View>
)
}
ShowHideTextComponentView:
ShowHideTextComponentView = (id) =>{
this.setState({
replyBoxShowId : id
})
}
I'm trying to render item using FlatList in React Native project. So my problem is when I render 2 items I can see the result but when there is only on item in my data array they is no result on my screen any idea why this is happening?
const data = this.getListPrise()
<View>
<View style={styles.allPAge} >
<View style={styles.centerText}>
<Text style={styles.text}>Voici vos differentes capture </Text>
</View>
<View style={{flex: 1}}>
<FlatList
data={data}
renderItem={({ item }) =>
<TouchableOpacity style={styles.container} onPress={() => this.modifCapture(item)}>
<Image style={styles.mark} source={avatar}></Image>
<View style={styles.displayUnder} >
<Text style={styles.textCapture}><Text style={styles.textCaptureTitle}>Espèce </Text>: {item.espece}</Text>
<Text style={styles.textCapture}><Text style={styles.textCaptureTitle}>Date </Text>:
{moment(item.date).format(" D MMMM YYYY, h:mm:ss")}</Text>
<Text style={styles.textCapture}><Text style={styles.textCaptureTitle}>Poids </Text> : {item.poids} kg</Text>
</View>
</TouchableOpacity>
}
style={{ flex: 1, flexDirection: 'column', padding: 1 }}
/>
</View>
<ActionButton buttonColor="rgba(231,76,60,1)" onPress={() => this.Addfish()}></ActionButton>
<View>
</View>
</View>
</View>
My problem so far, is following: I'm getting Tweets from Twitter Streaming API, so new data is appended to the bottom of the ListView, however the last item is not displayed in full, ie the last line of text (Text element), and there is no way I can scroll down to see that line.
My code for rendering ListView is:
renderRealtimeSearch() {
return (
<View
tabLabel='Realtime Search'
style={{padding: 10}}
>
<TextInput
style={{height: 40}}
placeholder="Type search query..."
onChangeText={(txt) => this.setState({query: txt})}
/>
<Button
onPress={() => this.handleStreamClick()}
style={styles.buttonStyle}
title='Submit query'
/>
{this.state.isStreamOn && <View style={{height: 515}}>
<ListView
ref='list'
onLayout={(event) => {
var layout = event.nativeEvent.layout;
this.setState({
listHeight : layout.height
});
}}
style={styles.realTweetsListView}
dataSource={this.state.realtimeTweets}
renderRow={(rowData) => {
console.log(rowData.text);
return (
<View>
<View style={styles.container}>
<Image source={{uri: rowData.avatar_url}} style={styles.photo}/>
<Text style={styles.title}>{rowData.author_name}</Text>
</View>
<View>
<Text style={styles.text}>{rowData.text}</Text>
<Text style={styles.date}>{`${rowData.date_time.week_day}, ${rowData.date_time.date}/${rowData.date_time.month}/${rowData.date_time.year} ${rowData.date_time.time} GTM`}</Text>
<Text style={styles.link}>{rowData.tweet_url}</Text>
</View>
</View>
);
}
}
renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.separator} />}
renderFooter={() => {
return (
<View onLayout={(event)=>{
var layout = event.nativeEvent.layout;
this.setState({
footerY : layout.y
});
}}>
</View>
);
}}
/>
</View>
}
</View>
);
}
And in the main render function (just in case this error caused by ScrollableTabView)
render() {
return (
<ScrollableTabView
renderTabBar={() => <DefaultTabBar />}
ref={(tabView) => { this.tabView = tabView; }}
>
{this.renderTwitterSearch()}
{this.renderRealtimeSearch()}
{this.renderDBSearch()}
</ScrollableTabView>
);
}
}
You can simply add a style property with flex=1 on the root component of the listview.
<View style={{flex: 1}}>
<ListView
style={{paddingBottom: 5, marginBottom: 0}}
enableEmptySections
dataSource={this.state.albums}
renderRow={album => <AlbumDetail key={album.title}
album={album}/>}
/>
</View>
In case it may be the help to others, I'd post a solution: in order to make this piece of code work, I wrap ListView and its children into ScrollView element, so code would be as follow:
renderRealtimeSearch() {
return (
<View
tabLabel='Realtime Search'
style={{padding: 10}}
>
<TextInput
style={{height: 40}}
placeholder="Type search query..."
onChangeText={(txt) => this.setState({query: txt})}
/>
<Button
onPress={() => this.handleStreamClick()}
style={styles.buttonStyle}
title='Submit query'
/>
{this.state.isStreamOn && <ScrollView style={{height: 520}}>
<ListView
renderScrollComponent={props => <InvertibleScrollView {...props} inverted />}
style={styles.realTweetsListView}
dataSource={this.state.realtimeTweets}
renderRow={(rowData) => {
return (
<ScrollView>
<View style={styles.container}>
<Image source={{uri: rowData.avatar_url}} style={styles.photo}/>
<Text style={styles.title}>{rowData.author_name}</Text>
</View>
<View>
<Text style={styles.text}>{rowData.text}</Text>
<Text style={styles.date}>{`${rowData.date_time.week_day}, ${rowData.date_time.date}/${rowData.date_time.month}/${rowData.date_time.year} ${rowData.date_time.time} GTM`}</Text>
<Text style={styles.link}>{rowData.tweet_url}</Text>
</View>
</ScrollView>
);
}
}
renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.separator} />}
/>
</ScrollView>
}
</View>
);
}