I have multiple Views inside my horizontal ScrollView. How can I set them such that each of those views has the exact dimensions as that of the ScrollView?
I want to use paging and go to my next View inside the ScrollView on swiping. I have tried to use width : "100%" but it does not work as ScrollView does not have fixed dimensions, but that is basically what I want to do with the views inside it. Here is my code:
export default class HorizontalScrollView extends Component {
render () {
screenWidth = "100%"
return (
<ScrollView
contentContainerStyle={styles.scrollable}
horizontal={true}
snapToInterval={screenWidth}
decelerationRate={"fast"}
>
<View style={StyleSheet.compose(styles.insideContainer, {"width" : screenWidth, "backgroundColor" : "red"})}>
<Text>Screen 1</Text>
</View>
<View style={StyleSheet.compose(styles.insideContainer, {"width" : screenWidth, "backgroundColor" : "blue"})}>
<Text>Screen 3</Text>
</View>
<View style={StyleSheet.compose(styles.insideContainer, {"width" : screenWidth, "backgroundColor" : "green"})}>
<Text>Screen 2</Text>
</View>
</
StyleSheet:
styles = StyleSheet.create({
"scrollable" : {
"backgroundColor" : "black",
"height" : "100%"
},
"insideContainer" : {
"alignItems" : "center",
"justifyContent" : "center",
"flex" : 1,
}
})
P.S. - I am using an Android Samsung Galaxy M30 to test this.
Any help or explanation would be appreciated.
Thank you.
Based on your code use these styles to accomplish what you want
<ScrollView horizontal={true} snapToInterval={Dimensions.get('screen').width} contentContainerStyle={{minHeight: '100%'}}>
<View style={{flexDirection: 'row'}}>
<View style={{width: Dimensions.get('screen').width, height: Dimensions.get('screen').height, backgroundColor: 'green'}}>
<Text>Screen 1</Text>
</View>
<View style={{width: Dimensions.get('screen').width, height: Dimensions.get('screen').height, backgroundColor: 'red'}}>
<Text>Screen 2</Text>
</View>
<View style={{width: Dimensions.get('screen').width, height: Dimensions.get('screen').height, backgroundColor: 'yellow'}}>
<Text>Screen 3</Text>
</View>
</View>
</ScrollView>
If your scroll view is the width of the screen, you can set each view inside to have a width of
Dimensions.get(“screen”).width
Then set the pagingEnabled prop of the ScrollView to true and you should have a paging scroller with full width sub views.
Related
I am quite new to react native. I have created a FlatList for rendering this list of items, however, it is not scrolling. I've googled it for hours and tried nearly everything suggested in stack overflow threads - removed flex, added flex, wrapped it in a view, but nothing seems to work.
Here is my code (the issue is in the second FlatList) -
return(
<View style = {{ height: '100%' }}>
<View style = {{ width: '100%' }}>
<AppHeader />
</View>
<View style = {{ width: '100%'}}>
<View style = {{ width: '70%', alignSelf: 'center', flex: 1 }}>
<View>
<FlatList
data = {this.getTodayDay()}
renderItem = {this.renderItemDays}
keyExtractor = {this.keyExtractor}
/>
</View>
<FlatList
data = {this.getVisibleHours()}
renderItem = {this.renderItem}
keyExtractor = {this.keyExtractor}
scrollEnabled = {true}
/>
</View>
</View>
</View>
this.renderItem -
renderItem = () => {
// irrelevant code
if( isClass === true ){
return(
<ListItem bottomDivider = {true} style = {styles.renderItemActiveClass}>
<ListItem.Content>
<TouchableOpacity
onPress = {()=>{
this.props.navigation.navigate('ClassDetailsScreen', { "data": classData })
}}>
<ListItem.Title>{ definiteClassTime }</ListItem.Title>
<ListItem.Subtitle>{ classData.class_name }</ListItem.Subtitle>
</TouchableOpacity>
</ListItem.Content>
</ListItem>
)
}
else{
return(
<ListItem bottomDivider = {true} style = {styles.renderItemClass}
containerStyle = {styles.renderItemContent}>
<ListItem.Content>
<ListItem.Title>{item}:00</ListItem.Title>
<ListItem.Subtitle>No Class</ListItem.Subtitle>
</ListItem.Content>
</ListItem>
)
}
}
the StyleSheet -
renderItemClass: {
borderColor: 'purple',
borderWidth: 2
},
renderItemActiveClass: {
borderColor: 'green',
borderWidth: 2
},
renderItemContent: {
},
Could somebody please tell me what I'm doing wrong?
Add a height to both the flatlist. And also wrap your second flatlist within a seperate view. Here is an example:
return (
<View style={{ height: "100%" }}>
<View style={{ width: "100%" }}>
<AppHeader />
</View>
<View style={{ width: "100%" }}>
<View style={{ width: "70%", alignSelf: "center", flex: 1 }}>
<View style={{ height: 60, alignSelf: "center" }}>
<FlatList
data={this.getTodayDay()}
renderItem={this.renderItemDays}
keyExtractor={this.keyExtractor}
/>
</View>
<View style={{ height: 60, alignSelf: "center" }}>
<FlatList
data={this.getVisibleHours()}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
scrollEnabled={true}
/>
</View>
</View>
</View>
</View>
);
i have a flatlist but it is not scrollable, first i set the height of it's parent container to screen height then i learned that it was a mistake to do so and also i didn't use flex:1 on any container still i can't scroll down.
so how to set the height of the flatlist to cover the entire screen and still be scrollable
return(
<LinearGradient style={DocumentStyle.box}
colors={['#053f5c','#00b1b2',"#429ebd"]}>
<DrawerIcon/>
{isEmpty ?
<View style={{flex:1}}>
<View style={DocumentStyle.conditions}>
<Icon style={{flex:.3,opacity:.3,fontSize:125,fontWeight:'bold'}} name="file-pdf-o" color="#666"/>
</View>
</View>
:
<View>
<DrawerIcon/>
<SafeAreaView>
<View style={DocumentStyle.searchBar}>
<Icon style={DocumentStyle.searchIconStyle} name="search" color="#666"/>
<TextInput
style={DocumentStyle.searchText}
value={search}
placeholder="Rechercher un fichier"
underlineColorAndroid='transparent'
onChangeText={(text)=>searchFile(text)}
/>
</View>
<View style={DocumentStyle.secondContainer}>
<FlatList style={DocumentStyle.flatstyle}
keyExtractor={(item)=>item['id']}
data={filteredfile}
renderItem={renderItem}
onRefresh={()=>onRefresh()}
refreshing={refresh}
/>
</View>
</SafeAreaView>
</View>
}
</LinearGradient>
);
import {StyleSheet,Dimensions} from 'react-native';
const width=Dimensions.get('window').width
const height=Dimensions.get('window').height
const DocumentStyle=StyleSheet.create({
box: {
width:width,
height: height,
},
secondContainer:{
backgroundColor:'white',
},
flatitem:{
backgroundColor:"white",
shadowColor:'#000',
shadowOffset:{
width:0,
height:2,
},
shadowOpacity:0.25,
elevation: 5,
color:'#666',
padding:10,
flexDirection:'row',
justifyContent:'space-between'
},
itemtext:{
flex:1,
fontSize:18,
color:'#666',
padding:10,
textAlign:'left'
},
pdf:{
fontSize:25,
padding:10,
},
ellipsis:{
fontSize:20,
paddingTop:15,
color:'#17224d'
},
searchBar:{
marginTop:60,
borderWidth:0.5,
alignSelf:'stretch',
borderColor:'#17224d',
borderRadius:15,
padding:2,
margin:10,
flexDirection:'row',
alignItems:'center',
backgroundColor:"#fff"
},
searchText:{
},
searchIconStyle:{
alignSelf:'flex-start',
fontSize:18,
alignSelf:'auto',
marginRight:10,
marginLeft:10,
opacity:0.5,
},
conditions:{
flex:1,
justifyContent:'center',
alignItems:'center',
alignContent:'center',
},
conditionText:{
color:'#666',
fontSize:18
}
})
export default DocumentStyle
Set flex:1 style to all parents of FlatList and also set contentContainerStyle to FlatList like below:
<FlatList contentContainerStyle={{flexGrow: 1}}
...
/>
I think your problem might be related to view hierarchy, your list is children of a LinearGradient component (to have a gradient background I suppose) and LinearGradient is blocking touch events to children views.
To prevent that, add pointerEvents={"none"} prop to LinearGradient.
I have a simple page that opens an image with a few styles. However, when I change the height to say... height: SCREEN_HEIGHT - 200, the image gets smaller but does not remain center. Also, it might even be cutting out the image. How can I fix this so I can make the image smaller but remain center?
If I give it a height: 100 and a width: 100, and position it with absolute or justify content, will it look the same across all devices?
Thank you guys for any input at all! I appreciate it more than you know.
import React from'react'
import { StyleSheet, Text, View, Dimensions, Image, Animated} from 'react-native'
const SCREEN_HEIGHT = Dimensions.get('window').height
const SCREEN_WIDTH = Dimensions.get('window').width
const Bars = [
{id : "1", uri: require('./assets/placeholder1.jpg')},
{id : "2", uri: require('./assets/placeholder2.jpg')},
{id : "3", uri: require('./assets/placeholder3.jpg')},
{id : "4", uri: require('./assets/placeholder4.jpg')},
{id : "5", uri: require('./assets/placeholder5.jpg')},
{id : "6", uri: require('./assets/placeholder6.jpg')},
{id : "7", uri: require('./assets/placeholder7.jpg')},
{id : "8", uri: require('./assets/placeholder8.jpg')},
{id : "9", uri: require('./assets/placeholder9.jpg')},
]
export default class App extends React.Component {
render() {
return(
<View style={{flex:1}}>
{/* styles header */}
<View style={{height: 60 }}>
</View>
{/* styles bar images */}
<View style={{flex: 1}}>
<Animated.View style={styles.barImage}>
<Image
style={{flex: 1 ,
height: null,
width: null,
borderRadius: 20
}}
resizeMode='cover'
source={Bars[0].uri} />
</Animated.View>
</View>
{/* styles footer if I even need it */}
<View style={{height: 60 }}>
</View>
</View>
)
}
}
const styles = StyleSheet.create({
barImage: {
height: SCREEN_HEIGHT - 170,
width:SCREEN_WIDTH,
padding: 10,
}
}
)
You are using resizeMode wrong. resizeMode is a prop of the <Image /> component. You have to wrap the <Image /> with a <View /> and give that <View /> a width and height and center that <View />.
<View style={{alignItems: 'center', justifyContent: 'center'}}>
<View style={{width: 100, height: 100}}>
<Image
...
resizeMode='cover'
...
/>
</View>
</View>
In your stylesheet, use the margin elements to center the image. If you set them to auto, it'll center them automatically. You can also use vertical-align and many other center components. Use this website for more context and better understanding with multiple other ways to suit your use case : https://www.w3.org/Style/Examples/007/center.en.html
Good evening!
I have been trying to create a modal with a scrollable FlatList inside, but such FlatList should have its height size reduced. The modal is going to search a wide list of airports, so basically a lot data might be shown, hence why FlatList is the best tool for this occasion. Basically, the modal screen would look like this picture below:
However, I can't make the scroll inside FlatList work no matter what. Here is the code, with the FlatList that is somewhat functional, but it has a warning:
const styles = StyleSheet.create({
modalContainer: {
backgroundColor: 'rgba(50,50,50,0.6)',
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
modalActivityContainer: {
backgroundColor: colors.colorWhite,
borderColor: colors.colorLightBlack,
borderWidth: 2,
borderRadius: 20,
padding: props.padding ? Number(props.padding) : 10,
maxWidth: '85%',
},
modalHeader: {
flexDirection: 'row',
justifyContent: 'center',
},
headerAirportModal: {
backgroundColor: colors.colorGrey,
borderTopRightRadius: 20,
borderTopLeftRadius: 20,
paddingHorizontal: 5,
paddingVertical: 10,
width: '100%',
justifyContent: 'center',
},
searchAirportBarContainer: {
backgroundColor: colors.colorWhite,
height: 40,
},
...
<Modal
onRequestClose={() => props.onRequestClose()}
animationType="fade"
transparent
visible={props.showModal}>
<TouchableWithoutFeedback
onPress={() => {
props.onRequestClose();
}}>
<View style={styles.modalContainer}>
<TouchableWithoutFeedback>
<View style={styles.modalActivityContainer}>
<View style={styles.modalHeader}>
<View style={styles.headerAirportModal}>
<Item style={styles.searchAirportBarContainer} rounded>
<Icon
style={styles.iconSearchAirport}
type="FontAwesome5"
name="search"
/>
<Input
style={styles.searchAirportBarText}
placeholderTextColor={colors.colorLightBlack}
placeholder="Search by Airport, Country or City"
/>
</Item>
</View>
</View>
<View>
<View style={styles.modalHeader}>
<Grid style={styles.headerAirportModalBackground}>
<Text style={styles.headerAirportModalText}>Latest Searches</Text>
<TouchableOpacity style={styles.clearButtonLatestContainer}>
<View>
<Text style={styles.clearButtonAirport}>Clear</Text>
</View>
</TouchableOpacity>
</Grid>
</View>
</View>
<View style={{maxHeight: 250}}>
<ScrollView>
<View onStartShouldSetResponder={() => true}>
<FlatList
data={airportElements}
renderItem={renderAirportItem}
keyExtractor={(item) => item.id}
/>
</View>
</ScrollView>
</View>
<Button
backgroundColor={colors.colorRed}
alignSelf="stretch"
buttonStyle={styles.finishButton}
onPress={() => {
setModalSelectAirport(false);
}}>
Cancel
</Button>
</View>
</TouchableWithoutFeedback>
</View>
</TouchableWithoutFeedback>
</Modal>
If I use the FlatList inside the ScrollView like shown above, the code works as intended. However, I got this warning:
VirtualizedLists should never be nested inside plain ScrollViews
with the same orientation - use another VirtualizedList-backed
container instead.
Because of that, I can't use FlatList properly. Also, I have managed to make it work with .map, but it was advised to not use it as I am going to load a list with a lot of elements and that might cause lag.
I have managed to implement FlatList in another way like this:
<View
style={styles.airportLatestSearchListContainer}>
<FlatList
contentContainerStyle={styles.airportLatestSearchlist}
data={airportElements}
renderItem={renderAirportItem}
keyExtractor={(item) => item.id}
/>
</View>
This, however, prevents the user to scroll. The list remains static and the user can't scroll at all.
I have tried using {flex: 1, flexGrow: 1} in the parent View and FlatList itself, both don't work at all, even inside the FlatList container or the style.
Can someone please help me with this one? I really appreciate the time and effort! Thanks!
I have a view having text inside it. The component looks like this:
MyComponent = () => {
return (
<View style={styles.viewStyle}>
<Text style={styles.textStyle}>My Text</Text>
</View>
);
}
const styles = {
viewStyle: {
backgroundColor: '#006699',
height: 40,
justifyContent: 'center',
alignItems: 'center',
},
textStyle: {
color: '#000000',
fontSize: 16,
}
}
When this component gets used, I want my View to have a custom width such that it just wraps my text. Here's the visual clue:
It's about the original design of Layout with Flexbox.
You can make it work by either add flexDirection: 'row' to it's parent view (so it will stretch automatically related to <Text /> width),
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={styles.viewStyle}>
<Text style={styles.textStyle}>My Text</Text>
</View>
</View>
or give width to it directly.
<View style=[{styles.viewStyle}, {width: 50}]>
<Text style={styles.textStyle}>My Text</Text>
</View>
Result of option 1: