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%.
Related
My FlatList is not scrollable while my Modal is visible. I've tried a bunch of things but none seem to do the job. I'm building for Android. You can find the Expo snack here https://snack.expo.dev/#ordis45/modal_flatlist?platform=android. Code is as follows:
Any pointers in the right direction would be appreciated!
const styles = StyleSheet.create({
container: {
flex: 1,
},
modal: {
position: 'relative',
bottom: 0,
height: 20,
},
modalContent: {
backgroundColor: 'white',
padding: 22,
justifyContent: 'center',
alignItems: 'center',
borderColor: 'rgba(0, 0, 0, 0.1)',
},
openButton: {
backgroundColor: '#F194FF',
borderRadius: 20,
padding: 10,
elevation: 2,
position: 'absolute',
bottom: 20,
right: 20,
},
});
const myComp = () => {
const [modalVisible, setModalVisible] = useState(false);
return (
<View style={styles.container} overflow='scroll'>
<Modal
visible={modalVisible}
style={styles.modal}
transparent={true}
>
<View style={styles.modalContent}>
<Text>This is a modal</Text>
<TouchableOpacity onPress={() => setModalVisible(false)}>
<Text>Close</Text>
</TouchableOpacity>
</View>
</Modal>
<FlatList
style={{height: 300, position: 'relative', elevation: 1}}
data={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
renderItem={({ item }) => <Text style={{padding: 50}}>{item}</Text>}
/>
<TouchableOpacity onPress={() => setModalVisible(true)} style={styles.openButton}>
<Text>Open</Text>
</TouchableOpacity>
</View>
);
};
I tried things like changing the elevation and z-indices of the View component and the FlatList and Modal components- to no avail. I also tried setting supportedOrientations={['landscape']} but that didn't work either.
I have a react native code, using expo, with a graph with text. In Apple, this application is showing it twice. In Android, once.
Here is the code:
import { ScrollView, StyleSheet, Text, View, Alert, Dimensions } from 'react-native';
...
// Charts
import * as scale from 'd3-scale'
import { ProgressCircle, LineChart, XAxis, Grid } from 'react-native-svg-charts';
.... <Other Code> ...
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
<View style={{ padding: 10 }}>
<ProgressCircle
style={{ height: 150, width: 150 }}
startAngle={-Math.PI * 0.5}
endAngle={Math.PI * 0.5}
progress={this.state.perFirstTier}
progressColor={constants.BGC_GREEN}
strokeWidth={10}>
{* THIS IS WHAT IS DOUBLED*}
<Text key ='percentage' style={{
position: "absolute",
marginLeft: 65, marginTop: 50
}}>{(this.state.perFirstTier * 100).toFixed(0)}%</Text>
</ProgressCircle>
<View style={{ marginTop: -40, flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={styles.description}>{i18n.t('activityDashboard.firstGoalDesc')}</Text>
{/* Show colored badge if 100%*/}
{this.state.perSecondTier == 1
? <Image style={styles.medalImage} source={require('../../utils/images/silver_medal.png')}></Image>
: <Image style={styles.medalImage} source={require('../../utils/images/grey_medal.png')}></Image>
}
</View>
</View>
Here is an image comparison of Apple versus Android:
Why is this happening, and how can I make it only show once?
Because progress is already declared in the ProgressCircle component, and it's rendered inside it. Just remove the Text component from the ProgressCircle. I guess it has overflow hidden on Android so it's not displayed there.
if all else fails, try adding a rendering condition for iOS platform.
<ProgressCircle
style={{ height: 150, width: 150 }}
startAngle={-Math.PI * 0.5}
endAngle={Math.PI * 0.5}
progress={this.state.perFirstTier}
progressColor={constants.BGC_GREEN}
strokeWidth={10}
>
{/* THIS IS WHAT IS DOUBLED */}
{Platform.OS === 'ios'
? <View />
: (
<View>
<Text
key ='percentage'
style={{
position: "absolute",
marginLeft: 65,
marginTop: 50
}}
>
{(this.state.perFirstTier * 100).toFixed(0)}%
</Text>
</View>
)
}
</ProgressCircle>
I had a similar issue trying to render YAxis as < Text > on iOS14. I used < Text > because had a hard time using YAxis for putting the label at the top of the chart bar.
My specs:
{
"expo": "~39.0.2",
"react-native-svg-charts": "^5.4.0",
"react-native-svg": "12.1.0"
}
Code:
const Values = ({ x, y, data }) => {
return (
data.map((value, index) => {
return (
<Text
key={index}
style={{
color: '#6e6969',
fontSize: 10,
position: 'absolute',
left: x(index) + 1,
top: y(value) - 15
}}
>
{value}
</Text>
)
})
)}
<BarChart
style={styles.chart}
data={data.plot}
spacing={0.2}
svg={{ fill: 'rgba(134, 65, 244, 0.8)' }}
contentInset={{ top: 20, bottom: 20, left: 0, right: 0 }}
>
<Values />
</BarChart>
<XAxis
style={{ marginHorizontal: -10 }}
data={data.plot}
formatLabel={(value, index) => data.labels[index]}
contentInset={{ left: 30, right: 30 }}
svg={{ fontSize: 10, fill: colors.medium }}
/>
Result
What I needed to do was wrapper the < Text > into a < View > and the issue was solved:
Changed code:
const Values = ({ x, y, data }) => {
return (
data.map((value, index) => {
return (
<View key={index}>
<Text
style={{
color: '#6e6969',
fontSize: 10,
position: 'absolute',
left: x(index) + 1,
top: y(value) - 15
}}
>
{value}
</Text>
</View>
)
})
)}
Result
Both codes worked fine on Android, though.
I have tried using a FlatList and a map function to generate a list of entries, but I am getting random lines between the entries (see the blue part of my screenshot)
What is causing these and how can I remove them?
Here is my FlatList:
<FlatList
data={TriageTransfertData[0].content[0].content}
renderItem={({ item }) => (
<View style={styles.subentryContainer}>
<View style={styles.ttEntryFirst} />
<View style={styles.ttEntryContentSub}>
<Text style={styles.ttTextSub}>{item.text}</Text>
</View>
</View>
)}
keyExtractor={item => item.text} />
And here is the styling:
subentryContainer: {
flexDirection: 'row',
width: '100%',
},
ttEntryFirst: {
width: '2%',
backgroundColor: Colors.Blue
},
ttEntryContentSub: {
width: '98%',
justifyContent: 'center',
paddingLeft: responsiveWidth(2),
paddingTop: 10,
paddingBottom: 10,
borderTopWidth: 1,
borderColor: Colors.GreyLight
},
And finally, here is a screenshot (notice the unwanted line in the blue area):
I think you're talking about ItemSeparatorComponent. It's rendered by default in a FlatList, but you can override it passing a custom component or a blank code function.
Here is the brief doc.
Hope this helps!
As I want to overlap this icon with two other Views, as shown in the image. this code is working on IOS platform but not on android. please suggest if there is any solution for Android.
var tabs = ['Activity', 'Files', 'People'];
this.state = {
tabs
};
return (
<Container style={{backgroundColor: '#F5F5F5'}}>
<View style={styles.topStrip}>
{
this.state.tabs.map((tab, index) => (
<View key={index} >
<TouchableOpacity>
<Text style={styles.streamName}>{tab}</Text>
</TouchableOpacity>
</View>
))
}
<View style={{position: 'absolute', backgroundColor: 'transparent', alignItems: 'center', justifyContent: 'center', zIndex: 5, elevation: 24, marginTop: 15, marginLeft: 300}}>
<EIcon size={40} color='#2196f3' name={'circle-with-plus'} />
</View>
</View>
<View style={{zIndex: -1}}></View>
</Container>
);
}
}
const styles = StyleSheet.create({
topStrip: {
alignItems: 'center',
},
streamName: {
marginTop: 7,
marginBottom: 6,
flexDirection: 'row',
alignSelf: 'center'
}
}
});
<View
style={{
paddingLeft: ITEM_HEIGHT * 3,
flex: 1,
position: "absolute",
top: 0,
right: 0,
bottom: 0,
left: 0,
zIndex: -1
}}
>
<Image
style={styles.centerCircle}
resizeMode="contain"
source={Images.ballSmall}
/>
</View>
In android, to use zIndex you need css with position-properties with top,left,right,bottom css
Tested On: Zenfone 3, Android 7, React Native 0.55.4
This issue is not caused by zIndex (although it does cause problem on Android).
Your icon is put inside the upper container view. React Native on Android does not support overflow: visible. That's why you see your icon being clipped outside the container.
You may put the icon on the "page" component level to solve this issue.
You may also refer to https://stackoverflow.com/a/50991892/6025730.
I am currently using React-Native for an Android Project. I have been trying to make a TextInput field with an icon beside the field. However, for some reasons, I notice that the flexDirection: 'row' is not working if the TextInput is one of its child component. The whole view of the one that I apply the style will automatically disappear. This is a snippet of how my code looks like:
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<View style={{flexDirection: 'row'}}>
<Image
style={{height: 30, width: 30}}
source={require('./images/email-white.png')}
/>
<TextInput
style={{height: 40}}
underlineColorAndroid={'transparent'}
placeholder={'E-mail'}
placeholderTextColor={'white'}
onChangeText={(data) => this.setState({ username: data })} />
</View>
</View>
I also tried to wrap both component inside each individual view, but the problem still persists. Is there anyone who knows how to solve this? or anyone can confirm that this is a bug?
Your code with a small modification worked fine for me. The only thing I did was adding a width to the TextInput resulting in the icon being beside the text-input.
Working code:
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<View style={{flexDirection: 'row'}}>
<Image
style={{height: 30, width: 30}}
source={require('./images/email-white.png')}
/>
<TextInput
style={{height: 40, width: 300}}
underlineColorAndroid={'transparent'}
placeholder={'E-mail'}
placeholderTextColor={'white'}
onChangeText={(data) => this.setState({ username: data })} />
</View>
</View>
I had the same problem when I was building example code from the book Mastering React Native
The code had enclosed a TextInput field in a View with a flexDirection: 'row' and the child TextInput field was not accessible. Only the TextInput border was visible. After playing around with some of the suggestions on this page I found something that worked.
If the container view has a flexDirection: 'row'. Please make sure to add a flex: 1 into your textfield input. The image flex does not seem necessary. As soon as I added the flex: 1 to the styles.input sheet, the TextInput was accessible.
The following code works for me :
<View style={globalStyles.COMMON_STYLES.pageContainer}>
<View style={styles.search}>
<Image
style={{height: 30, width: 30}}
source={require('../../images/email-white.png')}/>
<TextInput
style={styles.input}
onChangeText={text => this.setState({ searchText: text})}
value={this.state.searchText}
placeholder={'Search'}
placeholderTextColor={globalStyles.MUTED_COLOR}/>
</View>
</View>
Local Styles :
const styles = StyleSheet.create({
input: {
flex: 1,
height: 35,
color: globalStyles.TEXT_COLOR,
borderColor: globalStyles.MUTED_COLOR,
backgroundColor: globalStyles.BG_COLOR
},
search: {
borderColor: globalStyles.MUTED_COLOR,
flexDirection: 'row',
alignItems: 'center',
borderRadius: 5,
borderWidth: 1,
// marginTop: 10,
// marginBottom: 5
}
})
Global Styles (styles/global)
export const COMMON_STYLES = StyleSheet.create({
pageContainer: {
backgroundColor: BG_COLOR,
flex: 1,
marginTop: 0,
paddingTop: 20,
marginBottom: 48,
marginHorizontal: 10,
paddingHorizontal: 0
},
text: {
color: TEXT_COLOR,
fontFamily: 'Helvetica Neue'
}
});
Hopefully this provides assistance to you guys. It took me a long time get something this simple working.
Try closing your Image tag...
<Image style={{width:30, height: 30}} source={require('./icon.png')} />
Also, add some dimensions to your TextInput...
<TextInput style={{height: 40, borderColor: 'gray', borderWidth: 1}} />
You might also need to set flex: 0 on the image and flex: 1 on the TextInput