I am trying to achieve a layout similar to the second layout of this image I would like to have a background image take about 40% of the screen and then a view below it with my content but I would like my logo to float in between the two. Similar to how the "G" sits between the image and the content. I tried having two views and nesting the logo inside the first view and tried to position absolute but I am having trouble centering it horizontally, making it 10% of the width and having a perfect circle, because it seems you cant use flex attributes on an absolute positioned element.
Here is my attempt
https://snack.expo.io/HkV0wEptE
To centered the logo, you can just put it in a View that have screen width and sets the alignItems to 'center'. Below are a simple sample of how to do this layout:
render() {
return (
<View style={myStyle.container}>
<View style={myStyle.topBanner} />
<View style={myStyle.contentArea}>
<Text style={myStyle.contentTitle}>HERE LIES CONTENT</Text>
</View>
<View style={myStyle.midLogoRow}>
<Image style={myStyle.midLogo} source={require('../../images/profile_achive.png')} />
</View>
</View>
);
}
and the stylesheet is as below:
const sWidth = Dimensions.get('window').width;
const sHeight = Dimensions.get('window').height;
const myStyle = StyleSheet.create({
container: {
flex: 1,
width: sWidth,
backgroundColor: '#fff',
},
topBanner: {
width: sWidth,
height: sHeight * 0.4,
backgroundColor: '#c5c5c5',
},
midLogoRow: {
position: 'absolute',
top: sHeight * 0.3,
left: 0,
width: sWidth,
alignItems: 'center',
},
midLogo: {
width: sHeight * 0.18,
height: sHeight * 0.18,
},
contentArea: {
marginTop: sHeight * 0.09,
alignItems: 'center'
},
contentTitle: {
fontSize: 18,
color: '#333',
fontWeight: 'bold',
},
});
as you can see; the row where the your logo's in (in my case it's profile_achieve.png) is placed at the lowest part so that it will be render on top of everything else. The top margin for the contentArea is set at 0.09 of screen height, which is logo height divide by 2.
Related
I'm having problems setting transparency for a View that is outside of the ScrollView. I'm using Expo. The idea is that when you scroll the long scrollview content, you should just about to see it behind the bottom view. I've tried the opacity property as well as setting the background color using rgba(x,x,x, 0.5) with no luck. It looks like anything outside the Scrollview is totally opaque in relation to the scrollview content behind it.
Basic Code (the link to the snack is below):
export default function App() {
return (
<View style={styles.container}>
<ScrollView>
<View style={styles.transparentWrapper}>
<Text style={styles.textElement}>This is some text wrapped in a transparent View</Text>
</View>
<Text style={styles.paragraph}>
Lorem....
</Text>
<Text style={styles.paragraph}>
Lorem ...
</Text>
</ScrollView>
<View style={styles.bottomPart}>
<Text style={styles.textElement}>This is some text. Its wrapping view is transparent but I cannot see the lorem text underneath it.</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
},
paragraph: {
fontSize: 30,
marginBottom: 15,
},
textElement: {
color: 'blue',
},
transparentWrapper: {
position: 'absolute',
height: 100,
justifyContent: 'center',
top: 450,
left: 50,
backgroundColor: 'transparent',
zIndex: 999,
},
bottomPart: {
height: 50,
backgroundColor: 'transparent',
}
});
Full snack is here:
https://snack.expo.dev/#wastelandtime/scrollview-transparency
Here's an expected outcome. The top blue text is wrapped in a transparent view (and this is what it's supposed to look like) it's not a problem as it's within the ScrollView.
The bottom blue text does not seem to honour any transparency in terms of the scroll content behind it (I'd like just to see the blue text with complete transparency on the wrapping View.
it can be achieved without position: 'absolute', with negative margin in this way,
bottomPart: {
height: 50,
backgroundColor: 'transparent',
marginTop: -50, // add this
}
using negative top margin the text can be pushed upwards
snack link here https://snack.expo.dev/CJBbhSCzg
Setting bottomPart position to absolute and bottom: 0
bottomPart: {
height: 50,
backgroundColor: 'transparent',
position: 'absolute',
bottom: 0
}
You should get something like this.
You may also want to add marginBottom: 50, to the last element inside the ScrollView if you'll put a solid element inside the bottom part.
Image of what I am envisioning
I'm trying to add a center tick mark to a slider.
Is it possible to vertically and horizontally center View 1 with respect to View 2 and at the same time render View 2 above View 1 (using zIndex)? I can accomplish this by placing View 1 below View 2 in the Y direction and set the margin of View 1 so it appears underneath View 2 (in the Z direction). Is that the correct way to do this?
Accomplishing this by fiddling with the margins seems like it could cause problems on different size screens.
Try giving view1 and view2 absolute positions, and place them in a parent container that centers vertically and horizontally. This will allow them to overlap without having to play with margin, and will naturally place the view2 on top of view1 without having to use zIndex
export default function App() {
return (
<View style={styles.container}>
<View style={styles.specialContainer}>
<View style={styles.tall}/>
<View style={styles.long}/>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ecf0f1',
padding: 8,
},
specialContainer:{
width:300,
aspectRatio:1,
backgroundColor:'pink',
alignItems:'center',
justifyContent:'center'
},
long:{
position:'absolute',
backgroundColor:'purple',
width:'60%',
height:24,
// alignSelf:'center'
},
tall:{
position:'absolute',
backgroundColor:'green',
height:'60%',
width:24,
// alignSelf:'center',
}
});
Try it out here
You can surround the Views with a parent View like so:
<View style={{ width: '100%', justifyContent: 'center', alignItem: 'center' }}>
//horizontal
<View style={{ zIndex: 1, elevation: 1, width: '100%', height: '20'% }}></View>
//vertical
<View style={{ zIndex: 0, elevation: 0, height: '100%', width: '20%' }}></View>
</View>
This will adjust dynamically depending on screen size since all height and width values are set using percentages.
Created a list component, it has an image, some text, and a button.
the image has a border radius and borderColor on it.
Problem:
the colored-border-radius on android isn't being recognized, but on iOS it works fine...
here's the code:
List:
import React, { useState } from 'react';
import {
View,
Text,
Image,
StyleSheet,
Modal,
FlatList,
Dimensions,
TouchableOpacity,
TouchableWithoutFeedback
} from 'react-native';
import { Svg, Path, G, Line } from 'react-native-svg';
const { width } = Dimensions.get('window');
const BlockList = (props) => {
const onPress = (name) => {
alert('Unblocking ' + name);
};
return (
<FlatList
style={styles.container}
data={props.data}
renderItem={({ item, index }) => (
<View style={styles.itemContainer}>
<View style={styles.leftSide}>
<Image source={item.img} style={styles.img} resizeMode={'contain'} />
<Text style={{ fontSize: 18, fontWeight: 'bold', color: '#454A66' }}>{item.name}</Text>
</View>
<View style={styles.rightSide}>
<TouchableOpacity onPress={() => onPress(item.name)} style={styles.btn}>
<Text style={{ fontWeight: 'bold', color: '#fff' }}>Unblock</Text>
</TouchableOpacity>
</View>
</View>
)}
/>
);
};
const styles = StyleSheet.create({
itemContainer: {
flexDirection: 'row',
width: width * 0.95,
backgroundColor: '#fff',
marginHorizontal: width * 0.025,
marginBottom: width * 0.02,
borderRadius: 18,
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: width * 0.02,
shadowColor: '#333',
shadowOffset: {
width: 3,
height: 3
},
shadowOpacity: 0.5,
shadowRadius: 3,
elevation: 5
},
img: {
borderRadius: 50,
borderWidth: 2,
borderColor: '#219F75',
height: width * 0.125,
width: width * 0.125,
marginHorizontal: width * 0.05
},
btn: {
borderRadius: 11,
backgroundColor: '#219F75',
padding: width * 0.0275
},
leftSide: {
flexDirection: 'row',
alignItems: 'center'
},
rightSide: {
marginRight: width * 0.05
}
});
export default BlockList;
here's what its supposed to look like (working correctly on iOS):
here's what is looks like on android (notice the square green border):
Why is this happening and how can I get my border radius?
if we want the view circle, we also realize it by setting the borderRadius equals half of the view height(width).
<View
style={{
borderWidth:1,
borderColor:'rgba(0,0,0,0.2)',
alignItems:'center',
justifyContent:'center',
width:100,
height:100,
backgroundColor:'#fff',
borderRadius:50,
}}
/>
In your situation, your image sets the resizeMode. so it did not show the effect you want. for that try to move it in a view or use resizeMode:stretch; resizeMode:cover or remove it.
<View style={styles.leftSide}>
<Image source={item.img} style={styles.img}/>
<Text style={{ fontSize: 18, fontWeight: 'bold', color: '#454A66' }}>{item.name}</Text>
</View>
img: {
borderRadius: width * 0.125*0.5,
borderWidth: 2,
borderColor: '#219F75',
height: width * 0.125,
width: width * 0.125,
marginHorizontal: width * 0.05
},
contain: Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or less than the corresponding dimension of the view (minus padding).
Try borderRadius:width * 0.125 under img style.
You set image width height dynamically but border radius static value when using lower resolution device of android sometimes image borderRedius is larger to image width that's why it's occurred.
Please set all attribute dynamically. It will be better if use image borderRedius half of the width
try this in img style
borderRadius: (width * 0.125)/2
You can try to change the resizeMode to "cover"
I want to create a View which has one rounded edge on it in react native as you can see in the image. I already have the white view as I want it to be. However, it should extend up to the black curve. What are my options and how can it be achieved?
Thank you in advance.
You can make the white view elliptical by adding a bottom border radius and scaling it up using the transform attribute.
Then if you place it partially above the second view, you will end up with the expected output.
Here is an example:
import * as React from 'react';
import { View, StyleSheet } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<View style={styles.first} />
<View style={styles.second} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
position: 'absolute',
width: '100%',
backgroundColor: '#fff',
},
first: {
backgroundColor: '#fff',
alignSelf: 'center',
width: 100,
height: 100,
borderBottomRightRadius: 50,
borderBottomLeftRadius: 50,
transform: [{ scaleX: 4 }],
zIndex: 1,
},
second: {
backgroundColor: '#333',
marginTop: -30,
height: 200,
zIndex: 0,
},
});
Here is the example in action.
I am adding a profile picture module in my app. I use borderRadius to make the image in the circle. It works fine with when I take an image from the assets folder but not working with when I render an image from URL. here is code
When image render from URL:
<View style={styles.MainContainer}>
<Image
source={{ uri: 'https://reactnativecode.com/wp-content/uploads/2018/01/2_img.png' }}
style={{ width: 150, height: 150, borderRadius: 150 / 2 }} />
</View>
When image renders from assets Folder:
<View style={styles.MainContainer}>
<Image source={require("../../assets/img/rupee.png")}
style={{ width: 150, height: 150, borderRadius: 150 / 2 }} />
</View>
Css code:
const styles = StyleSheet.create({
MainContainer:
{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
margin: 5,
paddingTop: (Platform.OS === 'ios') ? 20 : 0
}
});
After some trials, I found It was image URL problem. Image URL contains https. When I use an image URL with http instead https, It works fine and thanks guys for your effort and suggestions.
Try below code :
import React, { Component } from 'react';
import { Platform, StyleSheet, View, Image, Text } from 'react-native';
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.setFontSize}> Normal Image</Text>
<Image source={require('./images/logo.jpg')} style={styles.setBorder} />
<Text style={styles.setFontSize}> Border Radius Image</Text>
<Image source={require('./images/logo.jpg')} style={styles.setBorderRadius} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
setFontSize: {
fontSize: 20,
fontWeight : 'bold'
},
setBorder:
{
width: 170, // Setting up image width.
height: 170, // Setting up image height.
borderWidth: 3, // Set border width.
borderColor: '#F44336', // Set border Hex Color code here.
},
setBorderRadius:
{
width: 170, // Setting up image width.
height: 170, // Setting up image height.
borderWidth: 3, // Set border width.
borderColor: '#F44336', // Set border Hex Color code here.
borderRadius: 60, // Set border Radius.
}
});