How to shape shadows in React Native for android? - react-native

Package used: react-native-shadow
Problem: How to shape the shadow if the view is circular-shaped? I have used Avatar and want shadow behind it with the same shape.
Code Used:
<BoxShadow setting={{
width: 90,
height: 90,
color: "#000",
radius: 20,
opacity: 0.1,
x: 2,
y: 3,
style: { marginVertical: 7 }
}}>
<Avatar size={90} overlayContainerStyle={{ backgroundColor: '#bf1e2e' }} rounded title="GS" onPress={() => console.log("Works!")} activeOpacity={0.7} />
</BoxShadow>
Solution Tried: I tried making radius 44, 48 but gives error after 50 If someone can give a reason would be great.
Current Output:
Click Here: Shadow Shape is rectangular
Expected Output:
Click Here: Shadow Shape is circular and blurred

Please add and try this in your code:
<BoxShadow
setting={{
width: 90,
height: 90,
border: 10, //Add this
color: '#8d1622',
radius: 45, //Change here
opacity: 1, //Change here
x: 0, //Change here
y: 0, //Change here
style: { marginVertical: 7 },
}}>
<Avatar
size={90}
overlayContainerStyle={{ backgroundColor: '#bf1e2e' }}
rounded
title="GS"
onPress={() => console.log('Works!')}
activeOpacity={0.7}
/>
</BoxShadow>

Related

How can I make a gradient border around a circle in react-native? I am using LinearGradient but it fills in the circle instead

I want the black border to be gradient and I want the circle to be transparent.
Is there a separate library I can use or is there a way to go around this?
<LinearGradient
colors={['#00FFFF', '#17C8FF', '#329BFF', '#4C64FF', '#6536FF', '#8000FF']}
start={{x: 0.0, y: 1.0}} end={{x: 1.0, y: 1.0}}
style={styles.CircleShapeView}
>
</LinearGradient>
CircleShapeView: {
position: 'absolute',
top: 1,
left:50,
right: 0,
bottom: 0,
width: Dimensions.get('window').height /3,
height: Dimensions.get('window').height /3,
borderRadius: Dimensions.get('window').height / 2,
backgroundColor: 'transparent',
borderStyle: 'solid',
borderWidth: 5,
borderColor: 'black',
},
You can not give it as border but you can create a view inside of linear gradient to get the same effect.
Here is a snack where you can test it: https://snack.expo.dev/#truetiem/border-gradient
<LinearGradient
colors={['#00FFFF', '#17C8FF', '#329BFF', '#4C64FF', '#6536FF', '#8000FF']}
start={{ x: 0.0, y: 1.0 }}
end={{ x: 1.0, y: 1.0 }}
style={{
width: 200,
height: 200,
borderRadius: 100,
padding: 5, // This should be the border width you want to have
overflow: 'hidden',
}}>
<View
style={{
flex: 1,
borderRadius: 100,
backgroundColor: '#ecf0f1',
alignItems: 'center',
justifyContent: 'center',
}}>
<Text>Your content goes here</Text>
</View>
</LinearGradient>

Chat bubble styling issue - react-native-gifted-chat

I am using react-native-gifted-chat in my react-native application. Chat Bubble style is not same on all bubble. I have used borderRadius: 30, For first message bubble shape is properly shown, from second message bubble shape of bubble is getting differed. I have added the following code:
<Bubble
{...props}
wrapperStyle={{
right: {
backgroundColor: colors.chatPurple,
borderRadius: 30,
borderBottomRightRadius: 30,
marginBottom: 10,
padding: 5,
right: 15,
justifyContent: "flex-end",
alignSelf: 'stretch',
marginLeft: 0,
alignSelf: "center"
},
left: {
backgroundColor: colors.lightGreen,
borderRadius: 30,
marginBottom: 20,
padding: 5,
left: -30
}
}}/>
I would like to get the Bubble shape as same on all Bubbles.
Setting the borderRadius for each corner separately (e.g. borderBottomRightRadius) works for me.
Simply setting borderRadius won't work because the borderBottomRightRadius, borderTopRightRadius etc. in the react-native-gifted-chat code overrides it, since the more exact style (separate for each corner) always overrides the more general style (same for every corner).
I faced a similar issue where I wanted a radius on 3 out of 4 corners, but it only worked for the first bubble:
After setting the BorderRadius properties on the containerToPreviousStyle, containerToNextStyle and containerStyle props, I got it to work as expected:
The code is as follows:
const renderBubble = props => {
return (
<Bubble
{...props}
{/* copy what you have in wrapperStyle */}
wrapperStyle={{
right: { borderTopRightRadius: 15 },
left: { borderTopLeftRadius: 15 },
}}
{/* and paste it into the follow 3 */}
containerToPreviousStyle={{
right: { borderTopRightRadius: 15 },
left: { borderTopLeftRadius: 15 },
}}
containerToNextStyle={{
right: { borderTopRightRadius: 15 },
left: { borderTopLeftRadius: 15 },
}}
containerStyle={{
right: { borderTopRightRadius: 15 },
left: { borderTopLeftRadius: 15 },
}}
/>
);
};
add this bubble with a BordeRadius
or just add container style
<Bubble
{...props}
wrapperStyle={{
right:
{
height: 200,
backgroundColor: 'blue',
},
}}
/>
Use this code
<Bubble
{...props}
wrapperStyle={{
right: {
backgroundColor: '#EFE5D9',
borderBottomRightRadius: 0,
borderBottomLeftRadius: 15,
borderTopRightRadius: 15,
borderTopLeftRadius: 15,
},
left: {
backgroundColor: '#F9F5F0',
borderBottomRightRadius: 15,
borderBottomLeftRadius: 15,
borderTopRightRadius: 15,
borderTopLeftRadius: 0,
}
}}
/>

Icon image cutting off in tab navigator - react native

Using react-navigations - createBottomTabNavigator, im trying to push the icons down a bit but its getting cut off and im not sure as to why.
Is there a way to fix this by any chance? or if you could direct me to some info about this.
The icon style is below:
<Icon
name="heart"
color={tintColor}
size={28}
style={{ marginTop: '20' }}
/>
And heres the tab bar options:
tabBarOptions: {
showLabel: false,
activeTintColor: '#e91e63',
indicatorStyle: {
height: 100
},
style: {
position: 'absolute',
backgroundColor: 'transparent',
height: 50,
width: DEVICE_WIDTH * 0.94,
borderTopColor: 'transparent',
borderBottomLeftRadius: 33,
borderBottomRightRadius: 33,
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
bottom: 0,
margin: 10,
shadowColor: '#000000',
shadowOffset: {
width: 0,
height: 0.3
},
shadowRadius: 5,
shadowOpacity: 0.1
},
tabStyle: {}
}
Many thanks in advance
Thanks for Samitha, had to set the icon height:
<Icon
name="heart"
color={tintColor}
size={28}
style={{ marginTop: 30 , height: 28 }}
/>
The bottom of the iPhone X is reserved for the home swipe bar
react-navigation like allot of other libraries implement the new SafeAreaView or add their own padding to the bottom of the iPhone X to stop you from putting content in that zone.
It's unlikely your buttons will work properly if placed that low so there's not much you can do here.

React Native rounded image with a border

I want to create a rounded image with a border. If I add borderColor: 'green', borderWidth:1, border is visible only in top left part of the rounded image.
<TouchableHighlight
style={[styles.profileImgContainer, { borderColor: 'green', borderWidth:1 }]}
>
<Image source={{ uri:"https://www.t-nation.com/system/publishing/articles/10005529/original/6-Reasons-You-Should-Never-Open-a-Gym.png" }} style={styles.profileImg} />
</TouchableHighlight>
export default styles = StyleSheet.create({
profileImgContainer: {
marginLeft: 8,
height: 80,
width: 80,
borderRadius: 40,
},
profileImg: {
height: 80,
width: 80,
borderRadius: 40,
},
});
overflow: 'hidden' for images container solves this issue.
Use the following styling, it's work for me.
image: {
width: 150,
height: 150,
borderRadius: 150 / 2,
overflow: "hidden",
borderWidth: 3,
borderColor: "red"
}
Worth to mention for Android...
I had to specifically set resizeMode="cover" for the borderRadius to take effect.
<Image
style={styles.image}
source={source}
resizeMode={"cover"} // <- needs to be "cover" for borderRadius to take effect on Android
/>
const styles = StyleSheet.create({
image: {
width: 150,
height: 150,
borderColor: 'red,
borderWidth: 2,
borderRadius: 75
},
});
Border width adds up to the size of the component that you added to. This makes your image bigger than the size of your container component. To solve this issue you can add the border width to the component sizes.
Example
const styles = StyleSheet.create({
profileImgContainer: {
marginLeft: 8,
height: 82,
width: 82,
borderRadius: 40,
borderWidth: 1
},
profileImg: {
height: 80,
width: 80,
borderRadius: 40,
},
});
If you want to show the image with rounded corner and with resizeMode={'contain'} to show the full image then wrap the image inside a view and then give border radius to the view. it will work
<View style={styles.carImageHolder}>
<Image
source={{
uri: each?.usercar_details?.car_model?.sized_photo,
}}
resizeMode={'contain'}
style={styles.carImage}
/>
</View>
and the style part
carImage: {
width: '100%',
aspectRatio: 1 / 1,
},
carImageHolder: {
width: '28.3%',
aspectRatio: 1 / 1,
backgroundColor: '#d8d8d8',
borderRadius: 25,
overflow: 'hidden',
},
The answers given here, are nice, but, from my experience, it's better to use percentages of your available screen height, as the width and height dimensions of image. This will help a lot with responsiveness. Do it like this
import RN from 'react-native';
const SCREEN_HEIGHT = RN.Dimensions.get('window').height;
Then apply the following as the dimensions styling, to get a nice, responsive rounded image.
style={[
//... your other previous styles
{
resizeMode: 'cover',
width: SCREEN_HEIGHT * 0.15,
height: SCREEN_HEIGHT * 0.15,
borderRadius: (SCREEN_HEIGHT * 0.15)/2,
}
]}
The (*0.15 i.e 15% of screen height) is just my choice of sample dimensions, you can use higher or lower, depending on how big you want your image to be.

TextInput in absolute positioned LinearGradient doesnot focus

I have a component with 2 LinearGradient views, both of them with absolute position and one with TextInput. For this setting, TextInput never gains focus in Android.
Code:
class SearchScreen extends Component {
render() {
return (
<View style={{ flex: 1 }}>
<LinearGradient
colors={['blue', 'red']}
style={{
height: 80,
width: '100%',
position: 'absolute',
zIndex: 10,
elevation: 10,
top: 0,
left: 0,
}}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
>
<TextInput
style={{
backgroundColor: 'white',
height: 50,
paddingLeft: 15,
marginTop: 10,
marginBottom: 10,
marginRight: 20,
marginLeft: 20,
borderWidth: 0,
}}
placeholder={'search placeholder'}
onFocus={() => { console.log('onFocus: '); }}
onChangeText={(text) => { console.log('enter text: ', text); }}
onEndEditing={() => { console.log('endEditing: '); }}
/>
</LinearGradient>
<LinearGradient
colors={['red', 'blue']}
style={{
height: 150,
width: '100%',
position: 'absolute',
zIndex: 5,
elevation: 5,
}}
>
</LinearGradient>
</View >
);
}
}
export default SearchScreen;
React Native: 0.55.2
react-native-linear-gradient: 2.4.0
I found the problem is with the 2 absolute positioned LinearGradient View with Text Input. If I remove the one of the LinearGradient, the TextInput works fine as it should.
I've tried providing zIndex to the TextInput too, it doesn't work.
Thanks.
Seems like a bug in the zIndex for android, as it works fine for IOS.
You can use it the following way as a workaround by nesting of linear gradients so that there is no conflict for the overlay element that renders.
<LinearGradient
colors={['red', 'blue']}
style={{
height: 150,
width: '100%',
position: 'absolute',
zIndex: 5,
elevation: 5,
}}
>
<LinearGradient
colors={['blue', 'red']}
style={{
height: 80,
width: '100%',
position: 'absolute',
zIndex: 10,
elevation: 10,
top: 0,
left: 0,
}}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
>
<TextInput
style={{
backgroundColor: 'white',
height: 50,
paddingLeft: 15,
marginTop: 10,
marginBottom: 10,
marginRight: 20,
marginLeft: 20,
borderWidth: 0,
}}
placeholder={'search placeholder'}
onFocus={() => { console.log('onFocus: '); }}
onChangeText={(text) => { console.log('enter text: ', text); }}
onEndEditing={() => { console.log('endEditing: '); }}
/>
</LinearGradient>
</LinearGradient>