Is there a way to apply a shadow AND a borderRadius to a View component, with the shadow following the rounded corners ?
Currently you have to set overflow: 'hidden' for borderRadius to work, but doing so removes the shadows.
It apparently is an old and known issue in React Native, likely not going to be fixed in the near future. A workaround was proposed in this issue, of superposing two Views but no code sample was given.
Can anybody give a code example of this proposed solution ? Will it follow the rounded corners (I doubt it) ?
Is there a package with some native binding voodoo doing the trick ?
Is there another solution ?
I already tried the solution from this question but it did not work for a View, the borderRadius prop does not work and triggers a warning advising to nest it in a style prop.
You can make use of this tool to generate parameters to shadows for both android and iOS.
And the trick is to make two Views, one for shadow with transparent background, other for the Content itself, both of them with the same borderRadius so a basic card will look like this:
import React from 'react';
import {View, StyleSheet, Text} from 'react-native';
export default () => {
return (
<View style={styles.cardShadow}>
<View style={styles.cardContainer}>
<Text> Card Content </Text>
</View>
</View>
)
}
const styles = StyleSheet.create({
cardShadow: {
borderRadius: 16,
backgroundColor: 'transparent',
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 1,
},
shadowOpacity: 0.22,
shadowRadius: 2.22,
elevation: 3,
},
cardContainer: {
backgroundColor: '#fff',
borderRadius: 16,
overflow: 'hidden',
},
});
In essence this is what you need to make a View with shadow and rounded corners, you could add also some margin/padding and flexbox to make a nice floating card.
Yeah this is what they meant by that:
const shadowsStyling = {
width: 100,
height: 100,
borderRadius: 10,
shadowColor: "#000000",
shadowOpacity: 0.8,
shadowRadius: 2,
shadowOffset: {
height: 1,
width: 0
}
}
<View styles={shadowsStyling}>
<View styles={{width: '100%', height: '100%', borderRadius: 10, overflow: 'hidden'}} />
</View>
Related
I would like to have multiple callout which are alway open in the same way as Uber taxi app does.
The criteria I want are
Multiple Callouts
Callout can be pressed
I have two solutions. One is to always set callouts open by reference once it is mounted, but it comes with only one active callout at once. Secondly, I use custom Marker with absolute position and TouchableOpacity as child. I can display multiple, but the button nested in <MapView.Marker> cannot be pressed.
I was struggling with the same problem for sometime. Actually this is how I stumbled across this question. I wanted to share what I ended up with. Apparently we can place anything inside the Marker component, so putting a View and an Image inside did the trick:
<Marker coordinate={coords} style={styl.customMarker}>
<View style={styl.addressBox}>
<TouchableOpacity onPress={() => console.log('Click!')}>
<Text numberOfLines={2} style={styl.addressText}>
Some location address goes here
</Text>
</TouchableOpacity>
</View>
<Image source={require('../assets/locationPin.png')} />
</Marker>
const styl = StyleSheet.create({
customMarker: {
justifyContent: 'center',
alignItems: 'center'
},
addressBox: {
width: 150,
height: 45,
backgroundColor: '#fff',
paddingVertical: 5,
paddingHorizontal: 7,
borderRadius: 5,
borderWidth: 0.5,
borderColor: '#ccc',
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.3,
shadowRadius: 5,
elevation: 3
},
addressText: {
textDecorationLine: 'underline'
}
});
This is how it looks:
This is a Grab (Uber alternative) implementation. But you can play around with View and Image styles to achieve Uber like results.
Hope this helps someone in the future. Cheers!
I would like to know how to apply shadow only to the main outer view. Here on applying shadow, it's getting applied to all the inner elements
The trick to make the shadow props of parent don't inherit to children element, is to set a background color to the component on which you set the shadow. For example that would be:
<View
style={{ backgroundColor: '#fff' }}
shadowOffset={{height: 10}}
shadowColor='black'
shadowOpacity={0.5}
>
<Text>{title}</Text>
</View>
Unfortunately this only works with colored backgrounds – when setting a transparent background with RGBA or 'transparent' is doesn't help.
I cannot really answer based on a simple image, but from my previous experience, setting shadow offset to the required height and width should do the trick for the iOS.
Read more about it here: Shadow Offset
Here's a picture of what my card looks like with the following style used:
marginLeft: 10,
backgroundColor: 'white',
shadowColor: 'blue',
alignItems: 'center',
shadowOffset: {width: 3, height: 3 },
shadowOpacity: 1.0,
borderRadius: 10,
My card View
Hope it works out well for you.
Display custom shadow color >= 28 or >= P for above Sdk level 28
Code
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<View
style={{
shadowColor: 'purple',
height: 150,
width: '90%',
backgroundColor: 'white',
alignItems: 'center',
justifyContent: 'center',
//android specific
elevation: 10,
//ios specific
shadowOffset: { width: 1, height: 1 },
shadowRadius: 3,
shadowOpacity: 0.5,
}}>
<Text style={{ color: 'rgba(128,0,128,0.5)' }}>
Welcome to React Native
</Text>
</View>
</View>
In android we can adjust shadow by elevation property
In iOS we can adjust shadow by shadowOffset, shadowRadius,shadowOpacity property
Output android
Output iOS
Available library for further usage
react-native-shadow-2
react-native-drop-shadow
Create a Shadow.js
export const Shadow = (elevation) => { // Receive elevation as a prop
return {
elevation,
shadowColor: 'black',
shadowOffset: { width: 0, height: 0.5 * elevation },
shadowOpacity: 0.3,
shadowRadius: 0.8 * elevation,
};
};
import Shadow.js to the page where you want to apply
import Shadow from './Shadow' //path to Shadow.js
<View style={{Shadow(5)}}> // pass elevation as a prop to Shadow.js
</View>
if you want to use in styles
import Shadow from './Shadow' //path to Shadow.js
<View style={styles.shadow}>
</View>
const styles = StyleSheet.create({
shadow:{
...Shadow(5) //use spread operator
}
});
I am new to react native and I want to create a show of a view. I am
attaching the image below:-
For the solution I just thought that I would append a Image similar to the shadow, but is there any other way to create this by using any stylesheet?
My view code with css I am giving here
.
<View style={{width: '100%', height: 90, flexDirection:'row',marginBottom:15,flex:1}}>
<View style={{flex:2,backgroundColor:"#388E3C"}}></View>
<View style={{flex:5,backgroundColor:"#66BB6A"}}></View>
</View>
My full screen is here:-
if you want to create a shadow of the view you should use:
const shadowStyle = {
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 5,
},
shadowOpacity: 0.34,
shadowRadius: 6.27,
elevation: 10,
}
<View style={shadowStyle}/>
I use react-native-elements, and they make it easy to make an actual button appear "raised", or shadowed. I want to duplicate this look for TouchableOpacity.
Here's an example of the "raised buttons" with react-native-elements.
It is subtle, but noticeably makes a nice impact.
How would you go about mimicking this effect with TouchableOpacity?
And yes, I've gone through the docs. If I missed anything, please point it out... but I don't think anything is there to accomplish this. Thanks.
You can add the following styles to your TouchableOpacity to make it raised.
<TouchableOpacity style={styles.button} />
button: {
shadowColor: 'rgba(0,0,0, .4)', // IOS
shadowOffset: { height: 1, width: 1 }, // IOS
shadowOpacity: 1, // IOS
shadowRadius: 1, //IOS
backgroundColor: '#fff',
elevation: 2, // Android
height: 50,
width: 100,
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'row',
},
You can read more about them here.
IOS Specific Props
Android Specific Props
I'm designing a react-native application based on chat-platform. I'm currently stuck with the UI issue:
As you can observe, when I rotate the mobile screen, the textbox does not cover up the full-width space. I'm new to React-native and I tried a lot to fix this issue. I also used flex: 1 in the textBox which seems to work and filled up the whole width of the screen but it hides microphone icon and add files icon (+) from the screenshot-1 (i.e when mobile is in vertical position)
Here is the code:
export default StyleSheet.create({
textBox: {
backgroundColor: '#fff',
flex: 0,
alignItems: 'center',
borderTopWidth: 1,
borderTopColor: '#D8D8D8',
zIndex: 2
},
textArea: {
flexDirection: 'row',
alignItems: 'center',
flexGrow: 0,
backgroundColor: '#fff'
},
textBoxInput: {
textAlignVertical: 'center',
maxHeight: 120,
flexGrow: 1,
width: 1,
// paddingVertical: 12, needs to be paddingTop/paddingBottom because of iOS/Android's TextInput differences on rendering
paddingTop: 12,
paddingBottom: 12,
paddingLeft: 0,
paddingRight: 0
},
For the Android devices, the code seems to work fine. It will be great if anyone can help me out with this issue. :)
Try this
import { Dimensions } from 'react-native';
And then do this
let width = Dimensions.get('window').width
Now use the width variable as a width css property for the element like this.
myElement: {
width: width
}
or this
myElement: {
width: Dimensions.get('window').width
}
Make sure you give this to you outermost element to get the full width of the screen.
There could be many problems involved, however, in my case, to avoid this problems is setting width to '100%'. I don't know if it's the most optimal, but it works for me. Parents containers also should have that value, or at least make sure they fill all screen width