React Native - "Absolute" position and "zIndex" not working on Android - android

I'm building a react native app. I have a circular image with text above it which the user can click to go to another page.
This works great on iOS, however on Android I can't click. When I inspect on Android and click the TouchableHighlight it seems like the appBody view I have as a parent is what's being clicked. I stripped the whole page down and removed the appBody leaving just the TouchableHighlight and still won't click on Android phones.
I noticed as soon as I remove the absolute position from the viewTextWrap it then triggers the click! However without the absolute position the Test text and background color is behind the image. I was reading absolute position with zIndex causes issue on Android, and to fix this by using elevation. So anywhere I have a Zindex I added the same elevation , but still doesn't work.
Here is my code:
<View style={globalStyle.appBody}>
<TouchableHighlight style={{zIndex: 100, elevation: 100}} onPress={() => this._goToPage('Test')} underlayColor={'transparent'}>
<View style={styles.ImageWrap}>
<Image style={[globalStyle.ProfileImage, { top: -90 }]} source={{ uri: this.state.pic }} defaultSource={require('../../assets/images/placeholder.png')} />
<Image style={styles.viewImage} source={require('../../assets/images/test.png')} />
<View style={styles.viewTextWrap}>
<Text style={styles.viewText}>Test</Text>
</View>
</View>
</TouchableHighlight>
//More code in the body here
</View>
And the css for those classes:
appBody: {
backgroundColor: '#fff',
padding: 25,
height: '100%'
},
ImageWrap: {
position: 'relative',
backgroundColor: '#fff',
},
ProfileImage: {
position: "absolute",
zIndex: 100,
top: -68,
height: 136,
width: 136,
borderRadius: 136 / 2,
alignSelf: 'center',
},
viewImage: {
position: "absolute",
zIndex: 100,
elevation: 100, //Tried adding to match zIndez
alignSelf: 'center',
bottom: -50,
},
viewTextWrap: {
position: "absolute", //If I remove this, the click works but the text is behind the image
zIndex: 101,
elevation: 101, //Tried adding to match zIndez
alignSelf: 'center',
bottom: -32,
},
viewText: {
position: 'relative',
fontSize: 12,
textAlign: "center",
},

Instead making position absolute for viewTextWrap, you can use ImageBackground component so that text viewTextWrap doesn't go behind the Image.

Related

React Native - keep the middle child centered with variable-width children on either side?

This is my desired outcome:
I want the green and blue boxes to always be the same length, such that the red box is always centered. The purple box is variable width, based on it's children. The yellow box always stays the same.
At the same time, I would like the red box to grow as big as possible. The centered text may need truncation, and I'd like to use as much space as I can to fit the text the best it can.
I've tried about a million combinations of flex, flexGrow, flexShrink, flexBasis - unfortunately nothing is working. I reached out to a long-time programmer friend of mine, he seems to think this is impossible with pure flexboxes.
Here's my code:
import React from "react";
import { StyleSheet, View } from "react-native";
function App() {
return (
<View style={styles.app}>
<View style={styles.container}>
<View style={styles.leftControlWrapper}>
<View style={styles.leftChild} />
</View>
<View style={styles.middle} />
<View style={styles.rightControlWrapper}>
<View style={styles.rightChild} />
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
app: {
marginHorizontal: "auto",
maxWidth: 500
},
container: {
display: "flex",
flexDirection: "row",
width: 500,
height: 100,
backgroundColor: "red",
},
leftControlWrapper: {
display: "flex",
justifyContent: "center",
flexShrink: 1,
alignItems: "flex-start",
backgroundColor: "green",
},
leftChild: {
width: 150,
height: 75,
marginHorizontal: 10,
backgroundColor: "purple",
},
middle: {
backgroundColor: "red",
flexGrow: 1,
flexShrink: 1,
},
rightControlWrapper: {
display: "flex",
justifyContent: "center",
flexShrink: 1,
alignItems: "flex-end",
backgroundColor: "blue",
},
rightChild: {
width: 100,
height: 75,
marginHorizontal: 10,
backgroundColor: "yellow",
},
});
export default App;
Here is the result. What I need is some combination of flexGrow/flexShrink to ensure the green and blue boxes are the same size. Like I said, I'm not even sure if this is possible.
Thanks so much in advance to anyone that knows the solution to this!

Make items float out of a scroll view with position absolute, on React Native Android

I am trying to create a component which resides inside a scroll view. The component has a small section which pops out of the scroll view component. The below image shows how my implementation looks like on IOS.
However on android the edges seem to be cut off when it leaves out of the scroll view container.
The code i have used for this implementation is as follows
<TouchableOpacity
onPress={_selectDate}
style={styles.container}
>
<View style={styles.count}>
<Text style={styles.countText}>20</Text>
</View>
<Text style={{ ...styles.label, ...styles.date }}>{fmtDate}</Text>
<Text style={styles.label}>{day}</Text>
</TouchableOpacity>
Given below is the style of the mentioned component.
const styles = StyleSheet.create({
container: {
zIndex: 100,
paddingHorizontal: SCREEN_EDGE_PADDING,
paddingVertical: SCREEN_EDGE_PADDING,
backgroundColor: LIGHT_GREY,
borderRadius: 10,
marginHorizontal: 5,
},
label: {
color: TEXT_DARKER_GREY,
textAlign: 'center',
fontFamily: ROBOTO,
},
date: {
// marginTop: 5,
fontFamily: ROBOTO_MEDIUM,
fontSize: 16,
},
count: {
position: 'absolute',
right: -2,
top: -2,
zIndex: 100,
padding: 2,
borderRadius: 10,
backgroundColor: TEXT_DARK_GREY,
},
countText: {
color: WHITE,
fontSize: 10,
},
});
The scroll view in which the above component resides has no additional stylings except for some padding and margins.
You can increase the margin of the container, it will give space for the floating label and won't be sliced anymore.

React Native - Make a view appear and follow screen after user scroll down enough, view apear and disappear too slow

I have a button that appear after user have scrolled down enough on a long screen that is contained in a ScrollView, I have some code for it and it works, however the view take a full second to appear and disappear and that's too slow! Is there anyway to make it appear and disappear faster?
const [showBottomButton, setShowBottomButton] = useState(false)
.
const handleScroll = (event) => {
var curY = event.nativeEvent.contentOffset.y;
if (curY>=500 && !showBottomButton){
setShowBottomButton(true)
}else if (curY<500 && showBottomButton){
setShowBottomButton(false)
}
}
.
{showBottomButton ? <View style={{ position: 'absolute', left: 0, bottom: 0, right: 0, height: 70, alignItems: 'center', justifyContent: 'center', backgroundColor: 'white', borderTopWidth: 1, borderColor: '#eeeeee' }}>
<TouchableOpacity onPress={BottomButtonOnpress}>
<View style={styles.BottomButton}
<Text style={styles.MediumText}>Button Text</Text>
</View></TouchableOpacity>
</View> : null}

TouchOpacity component set to position absolute unclickable in android

I've created a custom dropdown using TouchOpacity component of react native as follows.
<View style={dropDownStyle}>
<TouchableOpacity onPress={() => _switchTimeSpan('Day')}>
<Text style={dropDownItemStyle}>Day</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => _switchTimeSpan('Week')}>
<Text style={dropDownItemStyle}>Week</Text>
</TouchableOpacity>
</View>
The style is as follows.
dropDownStyle: {
position: 'absolute',
marginTop: 20,
width: 80,
},
dropDownItemStyle: {
marginTop: 5,
flex: 1,
textAlign: 'right',
},
When pressed the TouchOpacity component doesn't trigger the onpress function. This issue only exists in android and not IOS.
Edit 1 : There is a areachart created use react-native-svg-charts which is being overlapped by the mentioned dropdown. However upon inspecting if the reason for the onPress not working could be because of zIndex issues i noticed that the mentioned dropdown is the top most component.
The code for the chart is the following.
I am using react-native-svg-charts
<View style={containerStyle}>
<YAxis
data={data}
style={yAxisStyle}
formatLabel={value => yAxisFormat(value)}
contentInset={verticalContentInset}
numberOfTicks={5}
svg={axesSvg}
/>
<View style={chartWrapperStyle}>
<AreaChart
style={chartStyle}
data={data}
contentInset={verticalContentInset}
curve={shape.curveCatmullRom}
svg={{ fill: '#FF4D4D' }}
animate
/>
<View style={xAxisStyle}>
{
timeSpan !== 'Month' && (
<XAxis
data={data}
// formatLabel={(value, index) => months[value]}
formatLabel={(value, index) => xAxisPoints[index]}
contentInset={{ left: 10, right: 10 }}
// numberOfTicks={5}
svg={axesSvg}
/>
)
}
</View>
</View>
</View>
The style for the chart is as follows.
containerStyle: {
height: 200,
paddingLeft: 20,
paddingRight: 20,
flexDirection: 'row',
},
yAxisStyle: {
// marginBottom: 20,
position: 'absolute',
height: 180,
left: 20,
zIndex: 2,
},
chartStyle: {
flex: 1,
},
chartWrapperStyle: {
flex: 1,
},
xAxisStyle: {
marginHorizontal: -5,
height: 20,
},
When I'm testing this as isolated and only component on screen everything seems to work properly on Android (Samsung Galaxy Tab 2). Try to isolate this component and see if it will work for you on Android, maybe other components affect it. Also you could try to check if container component (with dropDownStyle) has some height or try to set 100%.

react native scrollview not scrolling on android

I have the following component:
export default class StoreComponent extends Component {
render() {
return (
<View style={styles.container}>
<ScrollView contentContainerStyle={styles.scroll}>
<StoreCarouselComponent />
<StoreDiscountComponent />
<StoreDetailsComponent />
</ScrollView>
</View>
);
}
}
with this style
import { StyleSheet, Dimensions, } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ffffff',
},
scroll: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center'
},
image: {
width: Dimensions.get('window').width,
height: 350,
},
box: {
width: Dimensions.get('window').width - 30,
position: 'absolute',
shadowColor: '#000000',
shadowOpacity: 0.34,
shadowRadius: 5,
shadowOffset: {
width: 0,
height: 10
},
elevation: 10,
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
borderBottomLeftRadius: 10,
borderBottomRightRadius: 10,
borderColor: 'lightgrey',
backgroundColor: '#ffffff',
padding: 10,
marginTop: 410,
},
boxDiscount: {
width: Dimensions.get('window').width - 30,
position: 'absolute',
shadowColor: '#000000',
shadowOpacity: 0.34,
shadowRadius: 5,
shadowOffset: {
width: 0,
height: 10
},
elevation: 10,
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
borderBottomLeftRadius: 10,
borderBottomRightRadius: 10,
borderColor: 'lightgrey',
backgroundColor: '#253241',
padding: 10,
marginTop: 320,
},
title: {
fontSize: 30
},
distance: {
fontSize: 20,
color: '#767676'
},
distanceElement: {
fontSize: 20,
color: '#44D9E6'
},
address: {
fontSize: 20,
color: '#767676'
},
category: {
fontSize: 20,
color: '#767676',
},
categoryElement: {
fontSize: 20,
color: '#44D9E6',
},
hr: {
borderBottomColor: 'lightgrey',
borderBottomWidth: 1,
},
icons: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
}
});
export default styles;
my scrollview works on ios but on android don't and I don't understand why
here a an image of the app and as you can see I need to scroll on android:
try to import from
import { ScrollView } from 'react-native-gesture-handler';
instead of from
'react native'
Use flexGrow : 1 inside your styles.scroll instead of flex:1
use flex: 1 inside style={styles.container} and delete it from .scroll
I had a similar issue. The culprit turned out to be contentContainerStyle={{flex: 1}} on my ScrollView. Removing that (It turned out to be unnecessary, anyway.) fixed the problem on Android.
the styles on your scroll contentContainerStyle is uneccessary
try to remove : styles.scroll
and just give padding or margin on component if you to center it
if its row add props horizontal = true on ScrollView.
I too had the similar structure as mentioned in question. I had 3 direct children View inside ScrollView and it wasn't scrolling. I tried all above solutions with flex, flexGrow etc. Nothing worked for me.
What worked for me is wrapping all 3 direct children to another View, so for ScrollView there's only one direct children.
// THIS DOES NOT SCROLL
<ScrollView>
<View>// 1st direct children</View>
<View>// 2nd direct children</View>
<View>// 3rd direct children</View>
</ScrollView>
// THIS WILL SCROLL, As now ScrollView has only one direct children
<ScrollView>
<View>
<View>// 1st children</View>
<View>// 2nd children</View>
<View>// 3rd children</View>
</View>
</ScrollView>

Categories

Resources