Is there a way to create a dropdown navigation menu like in HTML with React Native where the dropdown part is positioned absolute on top of the content that's below the menu?
Without absolute positioning, the dropdown's parent element (image below, blue background) increases its height and the other content is below the dropdown.
When I use position absolute on the dropdown, it's above Item 1 and not below it because React Natives position absolute positions relative to the parent.
My Code:
<View style={{ flex: 1 }}>
<View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'baseline', backgroundColor: '#3763a4'}}>
<View style={{ backgroundColor: '#FF0000', flex: 1 }}>
<View style={{ padding: 10 }}>
<Text style={{ color: '#FFFFFF' }}>Item 1</Text>
</View>
<View style={{ padding: 10 }}>
<Text style={{ color: '#FFFFFF' }}>Item 1.1</Text>
<Text style={{ color: '#FFFFFF' }}>Item 1.2</Text>
</View>
</View>
<View style={{ padding: 10, backgroundColor: '#FF0000', flex: 1 }}><Text style={{ color: '#FFFFFF' }}>Item 2</Text></View>
<View style={{ padding: 10, backgroundColor: '#FF0000', flex: 1 }}><Text style={{ color: '#FFFFFF' }}>Item 3</Text></View>
</View>
<WebView
source={myHtml}
/>
</View>
How it looks like:
The Webview is below this. Instead, the dropdown should be positioned in top of the Webview.
How it looks like with position absolute:
I hope my explanation is clear enough. This image and link shows a HTML navigation menu: https://www.w3schools.com/howto/howto_css_dropdown_navbar.asp
Absolute position exists in RN: https://reactnative.dev/docs/layout-props#position, it works almost same as on CSS. Try and investigate!
I've found a solution. I had to wrap the absolute positioned View in another View and add zIndex: 1 to position it on top of the Webview.
Code:
<View style={{ flex: 1 }}>
<View style={{ zIndex: 1, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'baseline', backgroundColor: '#3763a4' }}>
<View style={{ backgroundColor: '#FF0000', flex: 1 }}>
<View style={{ padding: 10 }}>
<Text style={{ color: '#FFFFFF' }}>Item 1</Text>
</View>
<View>
<View style={{ backgroundColor: '#FF0000', padding: 10, position: 'absolute' }}>
<Text style={{ color: '#FFFFFF' }}>Item 1.1</Text>
<Text style={{ color: '#FFFFFF' }}>Item 1.2</Text>
</View>
</View>
</View>
<View style={{ padding: 10, backgroundColor: '#FF0000', flex: 1 }}><Text style={{ color: '#FFFFFF' }}>Item 2</Text></View>
<View style={{ padding: 10, backgroundColor: '#FF0000', flex: 1 }}><Text style={{ color: '#FFFFFF' }}>Item 3</Text></View>
</View>
<WebView
source={myHTML}
/>
</View>
Result:
Related
I would like to have the grow horizontally not vertically. My current code is this
<View style={{ flexDirection: 'row', alignItems: 'center', backgroundColor: theme.backgroundColor }}>
<View style={{ flex: 1, height: 1, backgroundColor: 'white' }} />
<View>
<Text style={{ width: 50, textAlign: 'center', color: 'white' }}>Here is the problem</Text>
</View>
<View style={{ flex: 1, height: 1, backgroundColor: 'white' }} />
</View>
but this grows vertically any ideas.
You are limiting the width of the Text component, thus the text will not have enough space. Therefore, it will be breaking into several lines.
If we remove the fixed width, it will use the available vertical space.
<View style={{ flexDirection: 'row', alignItems: 'center', backgroundColor: theme.backgroundColor }}>
<View style={{ flex: 1, height: 1, backgroundColor: 'white' }} />
<View>
<Text style={{ textAlign: 'center', color: 'white' }}>Here is the problem</Text>
</View>
<View style={{ flex: 1, height: 1, backgroundColor: 'white' }} />
</View>
Before change
After change
Within a parent view, I would like to vertically center align one piece of text and have another at the bottom of the view.Whenever I add the bottom text, it shifts the position of the vertical centered view upwards (to make it the vertical center of the remaining space).
How do I keep the text vertically centered align relative to the parent view?
Update: I understand I can do this using {position: 'absolute',
bottom:0}, but want to understand the flex-box solution.
<View style={{height: 300, borderColor: "black", borderWidth: 1}}>
<View style={{ justifyContent: "center", flex: 1 }}>
<Text>Vert Middle</Text>
</View>
<View>
<Text>Vert Bottom</Text>
</View>
</View>
Just try below code
<View style={{height: 300, borderColor: "balck", borderWidth: 1}}>
<View style={{ backgroundColor: 'red', justifyContent: "center", flex: 1 }}>
<Text>Vert Middle</Text>
</View>
<View style={{position: 'absolute', bottom: 0}}> // Here is your updations
<Text>Vert Bottom</Text>
</View>
</View>
This is going to work for you. Also #Nitish answer is going to work too.
render() {
return (
<View style={{
height: 300,
borderColor: "black",
borderWidth: 1
}}>
<View style={{
justifyContent: "center",
flex: 1
}}>
<Text>Vert Middle</Text>
</View>
<View style={{
height:0, //Here...
justifyContent: "flex-end",
}}>
<Text>Vert Bottom</Text>
</View>
</View>
);
}
<View style={{height: '100%', width: '100%'}}>
{OtherContent}
<ScrollView>
<View style={{flexDirection: 'row', flexWrap: 'wrap', padding: 20}}>
{children}
</View>
<ScrollView>
</View>
I want the View inside ScrollView to be in center of the screen without changing it's children position
Children:
<View style={Styles.docsContainer}>
{arr.map((document, index) => {
return (
<TouchableOpacity key={index} style={[Style.docStyle} onPress={null}>
<Icon name='file-text-o'/>
<Text>{document.name}</Text>
</TouchableOpacity>
);
})}
</View>
const Styles: {
docsContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
padding: 20,
},
docStyle: {
alignItems: 'center',
padding: 20,
margin: 5,
marginBottom: 10,
borderRadius: 8,
width: 170
}
}
Indeed, we don't need parent View, we just need scrollView as flewGrow 1 which makes scrollView have full height and width as per device.
My approach:
<ScrollView contentContainerStyle={{ flexGrow: 1, justifyContent: 'center', alignItems: 'center' }}>
<View style={{
alignItems: 'center',
justifyContent: 'center',
flex: 1,
}}>
<Text>mahesh nandam</Text>
</View>
</ScrollView>
Try this.
The Viewis your ScrollView's immediate children. So you can style ScrollView using contentContainerStyle and align it in center like this.
<View style={{height: '100%', width: '100%'}}>
<ScrollView
contentContainerStyle={{
flexGrow: 1,
justifyContent: 'center',
alignItems: 'center',
}}
>
<View style={{flexDirection: 'row', flexWrap: 'wrap', padding: 20}}>
{children}
</View>
<ScrollView>
</View>
I guess it's what you're loooking for.
Center Horizontally
If you only want to center the View horizontally, you can set alignItems: 'center' to ScrollView's contentContainerStyle.
<View style={{ height: '100%', width: '100%' }}>
<Text>Other content</Text>
<ScrollView contentContainerStyle={{ alignItems: 'center' }}>
<View style={{ flexDirection: 'row', flexWrap: 'wrap', padding: 20, backgroundColor: 'red' }}>
<Text>children</Text>
</View>
</ScrollView>
</View>
The inner View is highlighted in red.
Center Horizontally and Vertically
In this case, you can set { flex: 1, justifyContent: 'center', alignItems: 'center' } for the same contentContainerStyle.
<View style={{ height: '100%', width: '100%' }}>
<Text>Other content</Text>
<ScrollView contentContainerStyle={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<View style={{ flexDirection: 'row', flexWrap: 'wrap', padding: 20, backgroundColor: 'red' }}>
<Text>children</Text>
</View>
</ScrollView>
</View>
If what you expect is different layout than in either of the screenshots, please share a simple sketch of the layout.
I have been struggling to align two items in the following positions: the first one should be on the left side of the row and the second element needs to be in the center of the row.
The following code below does not fully center my second element:
<View style={{flexDirection: 'row', justifyContent: 'space-between'}}>
<View style={{ paddingLeft: 10 }}>
<Text style={{ fontSize: 20, color: 'red', fontWeight: '200' }}>LEFT_ELEM</Text>
</View>
<View style={{paddingRight: 10 }}>
<Text>
CENTER
</Text>
</View>
{/* Empty view so that space-between works? */}
<View
style={{paddingRight: 10 }}>
</View>
</View>
This was the closest I could get to the result I wanted. However, it does not do the trick. Could anyone know the best way to implement this successfully?
You need to add flex: 1 to parent View and children Views (all children will have flex: 1 if you want them all to be of equal size, otherwise define width/flex for each child View individually).
Try this:
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}>
<View style={{ flex: 1, paddingLeft: 10 }}>
<Text style={{ fontSize: 20, color: 'red', fontWeight: '200' }}>LEFT_ELEM</Text>
</View>
<View style={{ flex: 1, paddingRight: 10 }}>
<Text style={{ textAlign:'center' }}>CENTER</Text>
</View>
<View
style={{ flex: 1, paddingRight: 10 }}>
</View>
</View>
Added style={{ textAlign:'center' }} to Text in center View child to give you an idea of its centered position. You can modify/remove it.
When I learned Android, I was told not to use too many 'layers' of components. In that philosophy, I decided to use 'absolute' property to the left element to achieve a simpler result. In this scheme, the 'left' item is almost stick to the left wall.
<View
style={{
height: 50,
flexDirection: 'row', // a must
alignItems: 'center', // to make items center vertically.
justifyContent: 'center' // to make the second item center horizontally.
}}
>
<MaterialIcons
style={[styles.titleIcon, { position: 'absolute', left: 0 }]} // on left, still center vertically.
name='arrow-back'
onPress={() => {
navigation.goBack();
}}
/>
<Text style={styles.titleText}>{result.name}</Text> // on center automatically
</View>
<View style={{flex:1, flexDirection: 'row', justifyContent: 'space-around'}}>
<View style={{width: 50, height: 50}}>
<Text style={{ fontSize: 20, color: 'red', fontWeight: '200' }}>LEFT_ELEM</Text>
</View>
<View style={{ width: 50, height: 50}}>
<Text>CENTER</Text>
</View>
<View style={{ width: 50, height: 50}}/>
</View>
I want to do this, where both of the texts are on 1 horizontal line and one of them is in the center and the other is on the right:
This is what I have, ignore the colors (it doesn't work at all):
styles:
rowLabelText: {
color: "#0B1219",
fontFamily: Fonts.Knockout31JuniorMiddleWeight,
fontSize: 16.0,
},
Markup:
<View style={{flexDirection: 'row', height: 30, flexWrap: 'wrap', backgroundColor: 'green'}}>
<View style={{ flex: 1, backgroundColor: 'red', justifyContent: 'center', alignSelf: 'center'}}>
<Text style={styles.rowLabelText}>
adjkfdasjkfaskj
</Text>
</View>
<View style={{ flex: 1, backgroundColor: 'blue', justifyContent: 'center', alignSelf: 'flex-end' }}>
<Text style={styles.rowLabelText}>
adjkfdasjkfaskj
</Text>
</View>
</View>
I am having trouble. Could someone assist me?
It looks like your problem is with with alignSelf you want to use alignItems.
This is how your code will look like.
Your View:
<View style={styles.textContainer}>
<View style={styles.leftContainer}>
<Text style={styles.rowLabelText}>
adjkfdasjkfaskj
</Text>
</View>
<View style={styles.rightContainer}>
<Text style={styles.rowLabelText}>
adjkfdasjkfaskj
</Text>
</View>
</View>
Your styles:
textContainer:{
flexDirection: 'row',
height: 30,
backgroundColor: 'green'
},
leftContainer:{
flex: 1,
justifyContent: 'center',
alignItems:'center',
backgroundColor: 'red',
},
rightContainer:{
flex: 1,
justifyContent: 'center',
alignItems: 'flex-end',
backgroundColor: 'blue',
},
rowLabelText: {
color: "#0B1219",
fontSize: 16.0,
},
One way to center text with respect to the entire width of the screen while also having some text to the right side of the centered text is to use absolute positioning on the right text.
By using absolute positioning on the right text, it will not affect the position of the centered text.
<View style={{flexDirection: 'row'}}>
<View style={{flex:1, alignItems: 'center', backgroundColor: 'red'}}>
<Text>50%</Text>
</View>
<View style={{position:'absolute', right: 20, backgroundColor: 'blue'}}>
<Text>+$0.80</Text>
</View>
</View>