react-native: borderRadius does not frame component right - mobile

The borderRadius style attribute doesn't change the border of a component correctly.
I would expect to see a green circle on the red background without any white space. Instead, I see this.
class Healthie extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.button} />
</View>
);
}
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red',
},
button: {
backgroundColor: 'green',
borderRadius: 50,
width: 100,
height: 100,
textAlign: 'center'
}
});
react-native version: 0.17.0.

no need to wrap button or text inside views, just put this on your style
overflow: hidden
it works for me

To get what you're looking for, you're going to have to wrap the Text box inside another View. The View will not default to another BG color when the borderRadius is changed:
<View style={styles.container}>
<View style={styles.button}>
<Text style={{ backgroundColor: 'transparent' }}>Text</Text>
</View>
</View>
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red',
},
button: {
backgroundColor: 'green',
borderRadius: 50,
width: 100,
height: 100,
textAlign: 'center',
flexDirection:'row',
alignItems:'center',
justifyContent:'center'
}
});
Check out this demo.

Related

I can't get text where it should go in react native

Hi I'm building an app for IOS and Android with react Native, and I'm a newbie this is my first app, and I think I'm not too bad, but I have a UI that is only a supermarket list, but I have the head ready but I need place the below the image , I made a new View but it comes out in the middle of the screen. Can you explain to me why it is not shown where to go, thanks.
Can you explain to me why? Thanks I share codes
enter image description here
import { Button, Image, StyleSheet, Text, View } from 'react-native';
import { StatusBar } from 'expo-status-bar';
export default function App() {
return (
<View style={styles.container}expoex>
<View style={styles.header}>
<View style={styles.imageContainer}>
<Image style= {styles.logo} source={require('./assets/logo.png')} />
</View>
<View style={styles.menu}>
<Image source={require('./assets/menu3.png')} />
<Image source={require('./assets/menu2.png')} />
<Image source={require('./assets/menu5.png')} />
<Image source={require('./assets/menu1.png')} />
<Image source={require('./assets/menu4.png')} />
</View>
</View>
<View style={styles.textNomList}>
<Text style={styles.textNom}>Lista de Supermercado</Text>
</View>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#6E04BF',
color: '#fff',
alignItems: 'center',
},
header: {
marginTop:62,
flex:1,
flexDirection:'row',
justifyContent:'center',
alignItems:'flex-start',
height: 145,
marginVertical: 10,
},
imageContainer: {
alignItems: 'center',
justifyContent: 'center',
marginLeft:5,
height: 145,
},
logo: {
width: 100,
height: 140,
},
menu: {
flex:1,
flexDirection:'row',
justifyContent:'space-between',
marginHorizontal: 20,
marginTop:15,
height:145,
},
textNomList: {
flex:1,
alignItems:'flex-start',
justifyContent:'flex-start',
},
textNom: {
color: '#fff',
fontSize: 16,
fontWeight: 'bold',
marginLeft: 20,
},
});
the result of this code is
enter image description here
I only can see some styling issues, check out below, edit it as required
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#6E04BF',
color: '#fff',
alignItems: 'center',
},
header: {
marginTop: 62,
// flex: 1,
flexDirection: 'row',
// justifyContent: 'center',
// alignItems: 'flex-start',
// height: 145,
// marginVertical: 10,
},
imageContainer: {
// alignItems: 'center',
// justifyContent: 'center',
marginLeft: 5,
height: 145,
},
logo: {
width: 100,
height: 140,
backgroundColor:'fff'
},
menu: {
// flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
marginHorizontal: 20,
marginTop: 15,
height: 145,
},
textNomList: {
flex: 1,
alignItems: 'flex-start',
justifyContent: 'flex-start',
},
textNom: {
color: '#fff',
fontSize: 16,
fontWeight: 'bold',
marginLeft: 20,
},
});
You should put your text in the same View that is wrapping your image and then style it appropriately.
<View style={styles.imageContainer}>
<Image style= {styles.logo} source={require('./assets/logo.png')} />
<Text style={styles.textNom}>Lista de Supermercado</Text>
</View>
I am not good at styling but it looks like your app should look decent with how the styles are at the current moment.

ripple effect leaking at corners as if Pressable button has a borderRadius

I'm using Pressable for buttons after referring this docs pressable docs
Now I want to add ripple effect to the button but it is not working properly.
<Pressable
android_ripple={{color: 'red', borderless: false}}
style={{backgroundColor: 'blue',borderRadius : 10}}>
<Text style={{alignSelf: 'center'}}>Button</Text>
</Pressable>
Ripple effect don't have border radius if button has radius.
it looks awkward that ripple effect corners go out of the curved radius.
Snack demonstrating the problem: https://snack.expo.dev/6U8dxxzLx
Nothing worked for me, So I solved this myself.
pressable should be wrapped in a view
view must have margin not padding
border radius must be on view not on pressable
pressable component must have padding not margin
then add ripple by android_ripple={{color: 'black', borderless: true}} to pressable.
<View style={styles.buttonView}>
<Pressable
onPress={() => {}}
android_ripple={{color: 'black', borderless: true}}
style={styles.loginButton}>
<Text style={styles.buttonText}>Login</Text>
</Pressable>
</View>
buttonView: {
alignSelf: 'stretch',
justifyContent: 'center',
borderRadius: 10,
elevation: 25,
margin: 10,
},
loginButton: {
height: 50,
backgroundColor: '#0f4c75',
padding: 10,
alignItems: 'center',
justifyContent: 'center',
},
buttonText: {
color: 'white',
fontSize: 16,
textTransform: 'uppercase',
fontFamily: 'sans-serif-light',
},
Update:-
Floating pressable component with ripple leakage fixed
<View style={{
position: 'absolute',
bottom: 250,
borderRadius: 50,
overflow: 'hidden',
alignSelf: 'center'
}}>
<Pressable
style={{
height: 60,
width: 60,
borderRadius: 50,
backgroundColor: 'red',
justifyContent: 'center',
alignItems: 'center',
elevation: 4,
}}
android_ripple={{
color: 'black',
}}
onPress={() => { console.log('om') }}>
<Text>O</Text>
</Pressable>
</View>
You can wrap pressable into View and pass borderRadius:10 and overflow:'hidden' to View style.
<View style={{ borderRadius: 10, overflow: 'hidden' }}>
<Pressable
android_ripple={{ color: 'red', borderless: false, }}
style={{ backgroundColor: 'blue', borderRadius: 10 }}>
<Text style={{ alignSelf: 'center' }}>Button</Text>
</Pressable>
</View>
Turns out the other solution don't cover all edge cases... I needed to wrap the view 2 times to manage elevation and shadow on iOS. (The button is in absolute position also).
export const PNFloatingButton = ({ children, ...props }) => {
return (
<View style={thisStyles.shadow}>
<View style={thisStyles.parentContainer}>
<Pressable style={thisStyles.button}
android_ripple={{ borderless: false, color: "#0F0" }}>
<Text>Button</Text>
</PNPressable>
</View>
</View>
)
}
const thisStyles = StyleSheet.create({
shadow: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.4,
shadowRadius: 4,
width: 56,
height: 56,
position: 'absolute',
elevation: 2,
right: 0,
bottom: 0,
},
button: {
padding: 4,
backgroundColor: "#F00",
},
parentContainer: {
// Pressable has issues with borderRadius on the ripple on android
overflow: "hidden",
borderRadius: 40,
},
})
For those that are using the Button element I found a simple workaround. Since this problem happens always when border od the button is changed (like became rounded) I just pass to the containerStyle of the button all the props + my button border radius. I add also the overflow property with hidden attribute.
Some little context: myButtonStyle is the style I want to apply to that button. If it's null, I'll apply a default style. Same for myContainerStyle.
The function inplemented before return():
function fixRippleBorder() {
const borderRadius = myButtonStyle
? EStyleSheet.flatten(myButtonStyle).borderRadius
: EStyleSheet.flatten(defaultButtonStyle).borderRadius;
return {
borderRadius: borderRadius,
overflow: 'hidden',
};
}
The button itself:
<Button
containerStyle={[
myContainerStyle ?? defaultContainerStyle,
fixRippleBorder(),
]}
buttonStyle={myButtonStyle ?? defaultButtonStyle}
...
You can add the style overFlow: 'hidden' to a view that wraps around your pressable object as long as that view also contains your borderRadius. Below is an example of a file I worked on recently that does this
import React from 'react';
import {Pressable, View, Text, StyleSheet, Platform} from 'react-native';
export default function CategoryGridTile({title, color, onPress}) {
return (
<View style={styles.gridItem}>
<Pressable
android_ripple={{color: '#ccc'}}
style={({pressed}) => [
styles.button,
pressed ? styles.buttonPressed : null,
]}
onPress={onPress}>
<View style={[styles.innerContainer, {backgroundColor: color}]}>
<Text style={styles.title}>{title}</Text>
</View>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
gridItem: {
flex: 1,
margin: 16,
height: 150,
borderRadius: 8,
elevation: 4,
backgroundColor: 'white',
shadowColor: 'black',
shadowOpacity: 0.25,
shadowOffset: {width: 0, height: 2},
shadowRadius: 8,
overflow: 'hidden',
},
button: {
flex: 1,
},
buttonPressed: {
opacity: 0.5,
},
innerContainer: {
flex: 1,
padding: 16,
borderRadius: 8,
justifyContent: 'center',
alignItems: 'center',
},
title: {
fontWeight: 'bold',
fontSize: 18,
},
});

Center a text in the screen with react native

I am trying to center a text vertically and horizontally on the screen. This is my code
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.header}>
<Text> Header </Text>
</View>
<Text style={styles.text}> some text in the middle center of the screen </Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor:'white',
alignItems:'center',
justifyContent:'center'
},
header: {
backgroundColor: 'green',
alignSelf: 'stretch',
alignItems: 'center',
heigth: 80 // this dose not change the header height
},
text:{
//flex: 1,
justifyContent:'center',
}
});
If I add the flex:1 to text, the header will also be centered which is not expected. I don't know if it's related but the I am also not able to modify the header view height. How can I solve this? The problems can be reproduced on this snack.
<div data-snack-id="S1urACbJM" data-snack-platform="ios" data-snack-preview="true" data-snack-theme="light" style="overflow:hidden;background:#fafafa;border:1px solid rgba(0,0,0,.16);border-radius:4px;height:505px;width:100%"></div>
<script async src="https://snack.expo.io/embed.js"></script>
This is one way to center text in the screen:
<View style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'blue'
}}>
<Text style={{backgroundColor: 'red'}}>
Your Text
</Text>
</View>
And you can also try with position:'absolute':
<View style={{
backgroundColor: 'blue',
position: 'absolute',
top: 0, left: 0,
right: 0, bottom: 0,
justifyContent: 'center',
alignItems: 'center'}}>
<Text style={{backgroundColor: 'red'}}> Your Text </Text>
</View>
I suggest setting the header as position:'absolute' , and use flex:1 and justify-content:'center' on the container.
Check the updated style
const styles = StyleSheet.create({
container: {
backgroundColor:'white',
alignItems:'center',
justifyContent:'center',
flex:1,
paddingTop:20 //this amount should be equal to the header height so that any items displayed inside the container will start after the absolute positioned header
},
header: {
backgroundColor: 'green',
alignSelf: 'center',
justifyContent:"flex-start",
alignItems: 'center',
position:"absolute",
top:0
}
});
Regarding the height you just have a typo in the word height

Fixed Position f

Hi I'm new in react native. I would like to ask how to fixed the position of these three colors, because every time i tried to click the search text input and the keyboard goes up those three colors will also goes up. I tried position: 'fixed' but it didnt work.
Screenshot
Here is also the code:
render(){
return(
<View style={{flex: 1}}>
<View style={{flex: 3, backgroundColor: '#E1F1FE'}}>
<View style={styles.form}>
<TextInput
style={styles.input}
placeholder = "Search"
returnKeyType="go"
underlineColorAndroid={'rgba(0,0,0,0)'}
/>
<Icon name="search" size={20} color="#900" style={styles.label} />
</View>
</View>
<View style={{flex: 1, backgroundColor: '#77D3F8'}}>
</View>
<View style={{flex: 1, backgroundColor: '#AEEAF2'}}>
</View>
<View style={{flex: 1, backgroundColor: '#39CFDE'}}>
</View>
</View>
);
}
and the styles
import {StyleSheet} from 'react-native';
module.exports = StyleSheet.create({
navBar: {
backgroundColor: '#EAEAEC',
},
title: {
color: '#rgba(0, 0, 0, 0.65)',
},
buttonText: {
color: '#rgba(0, 0, 0, 0.45)',
},
style3:{
fontSize: 35,
color: '#fff',
padding: 10,
alignContent:'center',
justifyContent: 'center',
},
style2: {
flexDirection: 'row',
alignContent: 'center',
alignItems: 'center',
flex:1
},
buttonstyle: {
flex: 1
},
form:{
flexDirection: 'row',
borderBottomWidth:1,
borderColor: '#00BBD1',
marginTop:80,
marginRight: 40,
marginLeft: 40,
alignContent: 'center',
alignItems: 'center',
},
input: {
height: 40,
borderWidth: 0,
flex: 1
},
label:{
alignContent:'center',
justifyContent: 'center',
marginRight: 10,
color: '#00BBD1'
},
});
Thank you in advance :)
It will not going to be stick to position when keyboard activated. You may need to use keyboardavoidingview or another package like react-native-keyboard-aware-scroll-view So design may not disturb when keyboard activated.

Flexbox positioning text inside image

I'm using React Native and trying to create a specific layout.
I have an image, vertically & horizontally centred (within a View) and some Text on top of the image also vertically & horizontally centred. The Text needs to come on top of image/background image therefore I put it inside the image tag.
Now the content of that text can be very long and because it is inside the image tag, it wraps.
How can I make it so the content inside Text won't wrap and still be on top of the Image?
My layout so far:
The layout I'm trying to achieve
My code:
<TouchableHighlight onPress={onPress}>
<View style={styles.categoryContainer}>
<View style={styles.leftContainer}>
<View style={styles.categoryIndexContainer}>
<Text style={styles.categoryIndex}>01</Text>
</View>
</View>
<View style={styles.middleContainer}>
<Image source={img} style={styles.categoryImage}>
<Text style={styles.categoryName}>Some very long title name</Text>
</Image>
</View>
<View style={styles.rightContainer}></View>
</View>
</TouchableHighlight>
const styles = StyleSheet.create({
categoryContainer: {
flexDirection: 'row',
},
leftContainer: {
width: 50,
paddingLeft: 15,
paddingTop: 30,
},
middleContainer: {
alignItems: 'center',
justifyContent: 'center',
flex: 1,
flexDirection: 'row',
},
rightContainer: {
width: 50,
},
categoryName: {
color: '#ffffff',
fontWeight: 'bold',
fontSize: 40,
textAlign: 'center',
backgroundColor: 'transparent',
flexWrap: 'nowrap',
},
categoryImage: {
alignItems:'center',
justifyContent:'center',
flexWrap: 'nowrap',
},
})
Thanks
You should specify on categoryName style: position: 'absolute' then set the top, left, right, bottom attributes until you place the Text above the Image.

Resources