'React Native - View disappears when position is absolute on Android
Whenever I made the position style 'absolute' for this view, it disappears. I have no idea why it is happening.
import React, { Component } from 'react';
import { Text, View, Image, TouchableOpacity, StyleSheet } from 'react-native';
export default class App extends Component {
render() {
return (
<View style={styles.mainView}>
<View
style={styles.parentView}>
<TouchableOpacity
activeOpacity={0.9}
onPress={() => {}}>
<View
style={ [{position: 'absolute'}, styles.textView] }>
<Text style={styles.textViewText}>
Just Another Cat
</Text>
</View>
<Image
style={[{position: 'absolute'}, styles.imageView]}
source={{ uri: 'https://images.pexels.com/photos/104827/cat-pet-animal-domestic-104827.jpeg' }}
/>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
mainView: { flexDirection: 'row', flex: 1 },
parentView: { alignSelf: 'center', flex: 0.5, left: 10, elevation: 3, alignItems: 'flex-start' },
textView: { width: 250, height: 250, opacity: 1, borderRadius: 125, backgroundColor: '#aaa034' },
textViewText: { textAlign: 'center', padding: 10, color: '#ffffff', fontSize: 18, top:0, right:0, bottom:0, left:0, textAlignVertical: 'center', position: 'absolute' },
imageView: { width: 250, height: 250, borderRadius: 125, borderColor: '#000000', borderWidth: 0.2 }
});
When I remove the inline-style: (position: 'absolute') added alongside styles.textView and styles.imageView, they both will be visible again. But I want to make the position absolute for some reason, but then they just disappear. I don't know why. Can anyone explain this?
EDIT: It works in iOS. It's giving this bug on android. Snack URL: https://snack.expo.io/Hy_oRrvOM
Solution 1:[1]
The problem is the width and height of the TouchableOpacity
are zero! because the contents of that are absolute, so you need to set (left, right, top, bottom) for one of the children or set the width and the height for the TouchableOpacity
itself
Why it works in iOS?
because in iOS UIView
doesn't clip its children by default, so actually TouchableOpacity
's width and height are still zero but the children overflowed and you can see them,
there is a flag for that (Docs)
but in android ViewGroup
always clips its children
How to solve problems like this?
there are some tools that you can debug UI at runtime, but I think the easiest way in react-native is set backgroundColor
from the root view to the target view!
so for example in this case: first set backgroundColor
for mainView
then if it does show, set backgroundColor
for parentView
and then for TouchableOpacity
and you can see it doesn't show backgroundColor
of TouchableOpacity
because the width
and height
of that are zero, in each step you can set width
and height
manually to ensure about the problem
Solution 2:[2]
Add zIndex:100
to your attributes. Worked for me. Not exactly, you just have to put a high enough value for your zIndex param, to put it on top of others.
Solution 3:[3]
I've just experienced this problem and it seems like specifying minWidth and minHeight for the parent of 'absolute' positioned elements solves the problem.
EDIT: Actually specifying width and height also solves it.
Here is the updated snack. See line 11.
Solution 4:[4]
I solved mine by giving parent component a flex:
position:'relative',
flex:1
Just dropping it soo it could be helpful to people.
Solution 5:[5]
It looks like z-index works from top to bottom.
Without setting the zIndex manually, your absolutely positioned component should be lower in order of appearance/line number in your code for it to layer over the content below it.
so
<Underlay/>
then
<AbsolutelyPositioned/>
and not the other way around.
Solution 6:[6]
I cannot comment because of I don't have enough rep, However, additional to what Amir Khorsandi said, you can also use onLayout to see what value you are getting. This way you can see it in your remote console log, even the x and y of the said View. I hope it helps.
<View onLayout={(event) => {
var {x, y, width, height} = event.nativeEvent.layout; console.log(x, y, width, height)}}>
Solution 7:[7]
All of the above solutions I have tried but none worked for me. Here is my style of View.
modal_continue_button:{
top:0,
backgroundColor:greentext ,
width:150,
height:40,
borderTopLeftRadius:30,
borderBottomLeftRadius:30,
alignItems:"center",
justifyContent:"center",
position:"absolute",
bottom:5,
zIndex:100,
},
Finally i have found a solution of this by adding the transform property to the style element. Now it is woring fine.
modal_continue_button:{
top:0,
backgroundColor:greentext ,
width:150,
height:40,
borderTopLeftRadius:30,
borderBottomLeftRadius:30,
alignItems:"center",
justifyContent:"center",
position:"absolute",
bottom:5,
zIndex:100,
transform: [{ scale: 1.1 }]
},
you can change the transform property to get the desired output.
Solution 8:[8]
I have solved the problem.
<View style={styles.container}>
<Text>Rooms Tab. {id}</Text>
<View style={styles.fab}>
<TouchableOpacity>
</TouchableOpacity>
<AntDesign name="plus" size={30} color="#ffffff" />
</View>
</View>
container: {
height: '100%',
},
fab: {
height: 50,
width: 50,
backgroundColor: colors.primary,
borderRadius: 50,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
position: 'absolute',
bottom: 1,
right: 1,
zIndex: 100
}
Solution 9:[9]
Basically <view>
tag higher zIndex, so it will hide behind prev absolute elements, So try to add negative zIndex: -1
<GooglePlacesAutocomplete .... styles={{ ..... listView: styles.listView, }} />
<View style={styles.field}> .... </View>
field: { zIndex: -1 },
Note: Above GooglePlacesAutocomplete
dropdown gets hide under below view element. So just zIndex: -1 will gives solution.Try this solution for sure
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | |
Solution 4 | ishab acharya |
Solution 5 | Mayowa Daniel |
Solution 6 | Slodin |
Solution 7 | |
Solution 8 | Sardorek Aminjonov |
Solution 9 | Vimalraj |