React Native: backgroundColor in View-Component is not working - react-native

I started to learn React Native two days ago and I am wondering why the backgroundColor "yellow" and "green" are not working. My whole screen is white. I thought that, because I used 3 times a flex: 0.5, that the screen is devided in 3 parts with different backgroundColors. What is the problem here? The dividing in 3 parts seems to work, because the text is, image and button are on the top 1/3, but the second 1/3 and third 1/3 are white.
Here is the code:
console.log("App executed");
return(
<View style={styles.viewStyles}>
<Text style={styles.textStyles} onPress={() => console.log("Text clicked")}>Beispielfüroben</Text>
<TouchableOpacity onPress={() => console.log("Bild clicked")}>
<Image source={require("./assets/books.jpg")} style={styles.logoStyles}></Image>
</TouchableOpacity>
<Button
style={styles.buttonStyles}
title= "Beispielbutton"
onPress={() => Alert.alert("Hallo", "I bims 1 clown",[{text: "hallo", onPress: () => console.log("Hallo clicked")}, {text: "no"}])}
></Button>
<View style={{backgroundColor: "yellow", flex: 0.5}}/>
<View style={{backgroundColor: "green", flex: 0.5}}/>
</View>
)
};
const styles = StyleSheet.create({
viewStyles: {
backgroundColor: "white",
flex: 0.5,
alignItems: 'center',
justifyContent: 'center'
},
Can you help me?
Thanks a lot :)

The issue here is that a View, which does not contain any children, won't fill any space unless we are telling it to do so.
The flex property will only
define how your items are going to “fill” over the available space along your main axis. Space will be divided according to each element's flex property.
Hence, let your Views occupy 100% of the available height and width. If the flex property is equal for both views, then the available space will be filled equally.
If you want to let the text, button and touchable opacity, occupy 1/3 of the screen, then you need to put them inside the same parent view with a flex of 1 as well and provide the same height and width percentage (100 in both cases).
export default function App() {
return (
<SafeAreaView style={styles.viewStyles}>
<View style={{ width: '100%', height: '100%', flex: 1, alignItems: 'center' }}>
<Text onPress={() => console.log('Text clicked')}>Beispielfüroben</Text>
<TouchableOpacity onPress={() => console.log('Bild clicked')}>
<Image
source={require('./assets/snack-icon.png')}
style={styles.logoStyles}></Image>
</TouchableOpacity>
<Button
title="Beispielbutton"
onPress={() =>
Alert.alert('Hallo', 'I bims 1 clown', [
{ text: 'hallo', onPress: () => console.log('Hallo clicked') },
{ text: 'no' },
])
}></Button>
</View>
<View
style={{
backgroundColor: 'yellow',
flex: 1,
width: '100%',
height: '100%',
}}
/>
<View
style={{
backgroundColor: 'green',
flex: 1,
width: '100%',
height: '100%',
}}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
viewStyles: {
backgroundColor: 'white',
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
logoStyles: {
width: 24,
height: 24,
},
});
The result is as follows
Here is a snack.

Related

React-Native make ScrollView childs take the width of the screen

I have a component with a ScrollView that works, and I want to add a scenario where for an example I want to fit all content on the screen width, and for other scenarios I want to scroll through them. How Can I achieve that ?
Here is my current Implementation:
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
style={styles.container}
contentContainerStyle={styles.containerContainer}
>
<View>
<View style={styles.tabs}>
{Object.keys(tabs).map((item, index) => {
const isSelected = item === selectedTab;
return (
<Tab
key={item}
item={tabs[item]}
select={() => select(index, item)}
setMeasures={(width) => setWidth(width, index)}
isSelected={isSelected}
gap={gap}
/>
);
})}
</View>
<Animated.View
style={[
styles.indicator,
{
transform: [{ translateX: value }],
},
measures[selectedIndex]
? { width: measures[selectedIndex] - gap }
: null,
]}
/>
</View>
</ScrollView>
and here is the stylings
indicator: {
backgroundColor: BURNING_ORANGE,
height: hp(2),
width: 0,
},
label: {
alignItems: 'center',
color: CLOUD_BURST,
fontFamily: CIRCULARMEDIUM,
marginVertical: hp(10),
},
selectedLabel: {
alignItems: 'center',
color: BURNING_ORANGE,
fontFamily: CIRCULARMEDIUM,
marginVertical: hp(10),
},
tab: {
alignItems: 'center',
flex: 1,
flexDirection: 'row',
paddingEnd: wp(20),
},
tabs: {
flexDirection: 'row',
},
Also, If I added flex: 1 to contentContainerStyle of my ScrollView the View just dissappear

React native Modal box content overflow

I am having the following modal box. Problem is whatever renderContent displays gets overflows visually outside the right boundary of modal box. How to fix it?
<Modal
transparent
animationType="fade"
visible={this.state.visible}
onRequestClose={this.hideModal}
>
<Container style={styles.overlay}>
<View style={[styles.container]}>
{ this.renderContent() }
</View>
</Container>
</Modal>
renderContent = () => {
return (
<ShopList
ref={ref => (this.shopList = ref)}
loadData={this.props.fetch}
/>
);
};
styles
overlay: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: Colors.overlay,
},
container: {
backgroundColor: Colors.white,
borderRadius: Metrics.WIDTH * 0.04,
flexDirection: 'column',
width: '96%',
},
Did you try this?
container: {
overflow: hidden,
backgroundColor: Colors.white,
borderRadius: Metrics.WIDTH * 0.04,
flexDirection: 'column',
width: '96%',
},
If not work, define max and min lengths to width content

How to add opacity to touchable opacity with image background in a flatlist?

I have a flatlist that renders a clickable item (with touchable opacity) and an image background with some text in the middle.
The goal is to render a flatlist that looks like this:
I am trying to add light opacity to the image by adding a view with an overlay and I tried multiple solutions but nothing seems to work.
This is what I have achieved so far:
This is the item in the flatlist:
// console.log("item", item.latest_image.media[0].url);
if (item.empty === true) {
return <View style={[styles.item, styles.itemInvisible]} />;
}
return (
<TouchableOpacity
onPress={() =>
this.props.navigation.push(Screens.Photos, {
team: item,
id: this.props.navigation.getParam("team").id
})
}
>
<ImageBackground
style={styles.backgroundImage}
imageStyle={{ borderRadius: theme.borders_MediumRadius.borderRadius, backgroundColor: 'rgba(255,0,0,.6)' }}
source={{ uri: item.latest_image.media[0].url }}
>
<Text style={styles.itemText}>{item.title.toUpperCase()}</Text>
</ImageBackground>
</TouchableOpacity>
);
};
This is the flatlist:
<SafeAreaView style={{ flex: 1 }}>
<ScrollView
style={{ flex: 1, backgroundColor: "black" }}
scrollEnabled={scrollEnabled}
onContentSizeChange={this.onContentSizeChange}
>
<FlatList
data={formatData(this.state.data, numColumns)}
style={styles.container}
renderItem={this.renderItem}
numColumns={numColumns}
scrollEnabled={scrollEnabled}
/>
<FollowUs />
</ScrollView>
</SafeAreaView>
);
and these are the style props:
container: {
margin: 7.5,
backgroundColor: "black"
},
backgroundImage: {
flex: 1,
height: hp("25"),
backgroundColor: "black",
margin: 7.5,
justifyContent: "center",
alignItems: "center"
},
itemInvisible: {
backgroundColor: "transparent"
},
itemText: {
fontFamily: "RobotoCondensed-Bold",
fontSize: RF(4),
color: "black"
},
overlay: {
backgroundColor: "rgba(255,0,0,0.5)",
alignItems: "center",
justifyContent: "center",
flex: 1,
margin: 7.5,
height: hp("25"), // approximate a square
borderRadius: theme.borders_MediumRadius.borderRadius
}
});
If anybody could help me it would be really appreciated!
Thanks
Here's an example of how you can achieve this
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<TouchableOpacity
style={{
backgroundColor: '#FFF',
height: 200,
width: 200,
position: 'relative'
}}>
<ImageBackground
source={{ uri: 'https://placehold.it/200x200' }}
style={{
height: 200,
width: 200,
opacity: 0.6,
position: 'absolute',
}}
/>
<View
style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Hello World!</Text>
</View>
</TouchableOpacity>
</View>
);
}
}
Here's an example Snack - https://snack.expo.io/#hannigan/lonely-bubblegum
You should also set the activeOpacity on the TouchableOpacity to be the same value as what you will set on the ImageBackground (0.6)
Solved it by adding a view around the text and giving it these props:
<View
style={{
flex: 1,
alignItems: "center",
justifyContent: "center",
backgroundColor: "rgba(255,255,255,0.75)",
borderRadius: theme.borders_MediumRadius.borderRadius
}}
>
<Text style={styles.itemText}>{item.title.toUpperCase()}</Text>
</View>

react native scrollView Height always stays static and does not change

I build react native app and I use with scrollView for header with list of text horizontal.
The issue is that the height of the scroll view takes half size of the screen. Even after declared it as a style, it still stays as it is.
screen with the scrollView
<View style={Style.container} >
{this.props.ExtendedNavigationStore.HeaderTitle ? <BackHeader header={this.props.ExtendedNavigationStore.HeaderTitle} onPressBack={this.goBack} /> : <Header openDrawer={this.openDrawer} />}
<ScrollView contentContainerStyle={{flexGrow:1}} style={Style.scrollableView} horizontal showsHorizontalScrollIndicator={false}>
{this.renderScrollableHeader()}
</ScrollView>
<Routes /> /* stack with dashboard screen */
</View>
</Drawer>
)
}
styles
import {StyleSheet} from 'react-native'
import {calcSize} from '../../utils'
const Styles = StyleSheet.create({
container : {
flex:1,
backgroundColor:"#e9e7e8"
},
scrollableView:{
height: calcSize(40),
backgroundColor: '#000',
},
textCategory:{
fontSize: calcSize(25),
color:'#fff'
},
scrollableButton:{
flex:1,
margin:calcSize(30)
}
})
export default Styles
As you can see the black size is the scroll View,
I want it to be small.
In routes stack into dashboard screen, the style:
const Style = StyleSheet.create({
container: {
backgroundColor: '#9BC53D',
flex: 1,
justifyContent: 'space-around',
alignItems: 'center'
},
text: {
fontSize: 35,
color: 'white',
margin: 10,
backgroundColor: 'transparent'
},
button: {
width: 100,
height: 75,
margin: 20,
borderWidth: 2,
borderColor: "#ecebeb",
justifyContent: "center",
alignItems: "center",
borderRadius: 40
}
})
There is an existing limitation with ScrollView where height cannot be provided directly.
Wrap the ScrollView in another View and give height to that View.
Like,
render() {
return (
<View style={styles.container}>
<View style={{height: 80}} >
<ScrollView
horizontal
style={{ backgroundColor: 'blue'}}
>
<Text style={{padding: 24}} >title1</Text>
<Text style={{padding: 24}} >title2</Text>
<Text style={{padding: 24}} >title3</Text>
<Text style={{padding: 24}} >title4</Text>
<Text style={{padding: 24}} >title5</Text>
</ScrollView>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
},
});
snack sample: https://snack.expo.io/HkVDBhJoz
EXTRAS: Unlike height providing width to a ScrollView will work correctly
Use flexGrow:0 inside ScrollView style
<ScrollView style={{ flexGrow:0 }}>
That worked for me:
<ScrollView contentContainerStyle={{ flexGrow: 1 }}>
<View style={{ flexGrow: 1 }}>
...
</View>
</ScrollView>
Considering the issue that you are using fixed height for the header, and flex for the Routes maybe, the orientation for different devices would not scale well and would look weird.
Therefore you may consider switching it to the flex
Here is the example by adding flexGrow to the styles of the ScrollView since it accepts view props
<View style={{ flex: 1 }}>
<ScrollView style={{ flexGrow: 0.05, backgroundColor: 'red', paddingTop: 50 }} horizontal>
<View style={{ width: 100 }}><Text>Label</Text></View>
<View style={{ width: 100 }}><Text>Label</Text></View>
<View style={{ width: 100 }}><Text>Label</Text></View>
<View style={{ width: 100 }}><Text>Label</Text></View>
<View style={{ width: 100 }}><Text>Label</Text></View>
</ScrollView>
<View style={{ flex: 0.95, backgroundColor: 'green' }} />
</View>
and here's the link to the snack expo
Use maxHeight inside scrollview style
<ScrollView style={{ maxHeight: 40 }}>•••</ScrollView>
Setting minHeight: int, maxHeight: int to ScrollView should work where int is height in pixels.
example below
<ScrollView style={{ minHeight: 280, maxHeight: 260}}>

KeyboarddAvoidingView not working with keyboard on bottom

I have a component that renders the following:
return (
<KeyboardAvoidingView behavior="position">
<View style={styles.container}>
<View style={styles.messagesContainer}>
</View>
<SafeAreaView>
<View style={styles.inputView}>
<TextInput style={styles.input} />
<Button title="submit" />
</View>
</SafeAreaView>
</View>
</KeyboardAvoidingView>
)
With stylesheet:
const styles = StyleSheet.create({
container:{
height: "100%"
},
messagesContainer: {
backgroundColor: "red",
flex: 1
},
inputView: {
flexDirection: "row",
alignItems: "center",
padding: 5,
height: 24
},
input: {
height: 20,
backgroundColor: "white",
flex: 1
}
});
This view is rendered as a screen in a react-navigation StackNavigation.
I'd like the view to move up to make space for the keyboard, but it doesn't seem to move up far enough.
I know it's moving it up, because if I add some padding to the bottom of my container:
I've also wondered whether the SafeArea component is messing up the calculations of how far up the view should be moved, but it doesn't seem so.
I could tweak that bottom padding until the text input shows up right above the keyboard, but that seems like a flaky solution that'd require different values for different devices, orientations, keyboard layouts, etc.
Is there a more robust solution?
Need some modification in styling try this
return (
<KeyboardAvoidingView behavior="position" style={styles.containerWraper}>
<View style={styles.container}>
<View style={styles.messagesContainer}>
</View>
<SafeAreaView>
<View style={styles.inputView}>
<TextInput style={styles.input} />
<Button title="submit" />
</View>
</SafeAreaView>
</View>
</KeyboardAvoidingView>
)
Styles
const styles = StyleSheet.create({
container:{
flex: 1,
justifyContent: 'center'
},
containerWraper:{
flex: 1,
justifyContent: 'center'
},
messagesContainer: {
backgroundColor: "red",
flex: 1
},
inputView: {
flexDirection: "row",
alignItems: "center",
padding: 5,
height: 24
},
input: {
height: 20,
backgroundColor: "white",
flex: 1
}
});
Try NativeBase instead, that has better approach