Ibrahim Ahmed
Ibrahim Ahmed

Reputation: 2345

How to set shadows in React Native for android?

Hi am trying to set a shadow for my fab but my attempts has failed so far i tried setting shadow props but that is for ios only so i tried to play with elevation property but it doesn't look right.

Here's what i tried

  <View
    style={{
      width: 56,
      height: 56,
      elevation: 2,
      borderRadius: 28,
      marginBottom: 3,
      backgroundColor: 'rgba(231,76,60,1)',
    }}
  ></View>

What i need to achieve

enter image description here

Upvotes: 94

Views: 227845

Answers (22)

Ian
Ian

Reputation: 2610

To be able to work with both mobile OS's and web I did the following:

import { Platform } from 'react-native';

   ...Platform.select({
      ios: {
        shadowOpacity: 0.3,
        shadowRadius: 3,
        shadowOffset: {
          height: 0,
          width: 0,
        },
        android: {
          elevation: 1,
        },
        web: {
          boxShadow: '2px 2px 2px 1px rgba(0, 0, 0, 0.2)',
        },
      },
    }),

Upvotes: 1

Zahir Masoodi
Zahir Masoodi

Reputation: 858

import React from "react";
import { View, StyleSheet } from "react-native";

const ViewShadow = ({ children }) => {
    return (
        <View style={styles.container}>
            <View style={styles.box}>{children}</View>
        </View>
    );
};

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
    },
    box: {
        width: 200,
        height: 200,
        backgroundColor: "fff",
        // Android
        elevation: 8,
        // shadow color
        shadowColor: "blue",
        //iOS
        shadowOffset: { width: 5, height: 5 },
        shadowOpacity: 0.26,
    },
});

export default ViewShadow;

Upvotes: 0

Umair Azhar
Umair Azhar

Reputation: 1

{
  shadowColor: '#d8d8d8',
  shadowRadius: 10,
  elevation: 1,
  backgroundColor: 'Color code'
}

You can set height and width as well on the View style.

Upvotes: 0

Dimitar Spassov
Dimitar Spassov

Reputation: 2733

The react-native-shadow library is already mentioned in the answers, but it seems to be abandoned for several years.

A modern alternative, which solved my issue with consistent shadows across both iOS and Android was react-native-shadow-2.

EDIT: I ended up using the native shadow solutions (and elevation for Android). According to the docs, Android API 28 and above supports shadowColor on elevated elements and it works well for my case.

Upvotes: 2

Christian
Christian

Reputation: 41

A simple solution is this one!

Click here to see preview of simple drop shadow

Does not flicker when rendering collapse elements:

    const styles = {
        simpleShadow: {
            borderTopWidth: 0.5,
            borderRightWidth: 1,
            borderBottomWidth: 1,
            borderLeftWidth: 0.5,
            borderTopColor: 'rgba(0,0,0,0.1)',
            borderRightColor: 'rgba(0,0,0,0.2)',
            borderBottomColor: 'rgba(0,0,0,0.2)',
            borderLeftColor: 'rgba(0,0,0,0.1)',

            backgroundColor: 'white',
            margin: 10,
            padding: 10,
            borderRadius: 10
        }
    }
    return (
        <View style={styles.simpleShadow}>
            <Text>Simple Shadow</Text>
        </View>
    );

Upvotes: 4

FuzzyTree
FuzzyTree

Reputation: 32392

Adding the CSS property elevation: 1 renders shadow in Android without installing any 3rd party library.

elevation is an Android-only style property available on the View elements.

See: React Native Docs for the elevation style property


If you're open to 3rd party software, another way to get shadows for android is to install react-native-shadow.

Example (adapted from the readme):

import React, { Component } from "react";
import { TouchableHighlight } from "react-native";

import { BoxShadow } from "react-native-shadow";

export default class ShadowButton extends Component {
  render() {
    const shadowOpt = {
      width: 160,
      height: 170,
      color: "#000",
      border: 2,
      radius: 3,
      opacity: 0.2,
      x: 0,
      y: 3,
      style: { marginVertical: 5 }
    };

    return (
      <BoxShadow setting={shadowOpt}>
        <TouchableHighlight
          style={{
            position: "relative",
            width: 160,
            height: 170,
            backgroundColor: "#fff",
            borderRadius: 3,
            // marginVertical: 5,
            overflow: "hidden"
          }}
        >
          ...
        </TouchableHighlight>
      </BoxShadow>
    );
  }
}

Upvotes: 154

Asad Ullah
Asad Ullah

Reputation: 1269

The elevation style property on Android does not work unless backgroundColor has been specified for the element.

Android - elevation style property does not work without backgroundColor

Example:

{
  shadowColor: 'black',
  shadowOpacity: 0.26,
  shadowOffset: { width: 0, height: 2},
  shadowRadius: 10,
  elevation: 3,
  backgroundColor: 'white'
}

Upvotes: 127

For some reason it only worked for my by adding borderColor: 'transparent' (or any other color). My style output looks like this:

{
        borderColor: "transparent", // Required to show shadows on Android for some reason !?!?
        shadowColor: '#000',
        shadowOffset: {
          width: 0,
          height: 0,
        },
        shadowOpacity: 0.3,
        shadowRadius: 5,

        elevation: 15,
      }

Upvotes: 2

RoyBS
RoyBS

Reputation: 1281

You can use my react-native-simple-shadow-view

  • This enables almost identical shadow in Android as in iOS
  • No need to use elevation, works with the same shadow parameters of iOS (shadowColor, shadowOpacity, shadowRadius, offset, etc.) so you don't need to write platform specific shadow styles
  • Can be used with semi-transparent views
  • Supported in android 18 and up

Upvotes: 6

Sahitya D
Sahitya D

Reputation: 166

I added borderBottomWidth: 0 and it worked fine for me in android.

Upvotes: 5

Yossi
Yossi

Reputation: 6027

Generating shadows for a circle, react native, android

Based on the answers here, and on text that I found in github (react-native-shadow), I made few tests and thought that some people may find the following helpful.

Here is how the screen looks like:

enter image description here

Code:

import React, { Component } from 'react';
import { View, TouchableHighlight, Text } from 'react-native';
import { BoxShadow } from 'react-native-shadow'

export default class ShadowsTest extends Component {

  render() {
    const shadowOpt = {
      width: 100,
      height: 100,
      color: "#000",
      border: 2,
      radius: 50,
      opacity: 0.8,
      x: 3,
      y: 3,
      //style: { marginVertical: 5 }
    }

    return (
      <View style={{ flex: 1 }}>
        <Header
          text={"Shadows Test"} />

        <View style={{ flexDirection: 'row', justifyContent: 'center' }}>
          <View style={{ margin: 10, alignItems: 'center',
              justifyContent: 'center' }}>
            <TouchableHighlight style={{
              position: 'relative',
              width: 100,
              height: 100,
              backgroundColor: "#fff",
              borderRadius: 50,
              borderWidth: 0.8,
              borderColor: '#000',
              // marginVertical:5,
              alignItems: 'center',
              justifyContent: 'center',
              overflow: "hidden" }}>
              <Text style={{ textAlign: 'center' }}>
                0: plain border
              </Text>
            </TouchableHighlight>
          </View>

          <View style={{ margin: 10, alignItems: 'center',
              justifyContent: 'center' }}>
            <BoxShadow setting={ shadowOpt }>
              <TouchableHighlight style={{
                position: 'relative',
                width: 100,
                height: 100,
                backgroundColor: "#fff",
                borderRadius: 50,
                borderWidth: 1,
                borderColor: '#aaa',
                // marginVertical:5,
                alignItems: 'center',
                justifyContent: 'center',
                overflow: "hidden" }}>
                <Text style={{ textAlign: 'center' }}>
                  1: RN shadow package
                </Text>
              </TouchableHighlight>
            </BoxShadow>
          </View>
        </View>

        <View style={{ flexDirection: 'row', justifyContent: 'center' }}>
          <View style={{ margin: 10, alignItems: 'center',
              justifyContent: 'center' }}>
              <TouchableHighlight style={{
                position: 'relative',
                width: 100,
                height: 100,
                backgroundColor: "#fff",
                borderRadius: 50,
                borderWidth: 1,
                borderColor: '#aaa',
                // marginVertical:5,
                alignItems: 'center',
                justifyContent: 'center',
                overflow: "hidden",
                shadowOffset: { width: 15, height: 15 },
                shadowColor: "black",
                shadowOpacity: 0.9,
                shadowRadius: 10,
               }}>
                <Text style={{ textAlign: 'center' }}>
                  2: vanilla RN: shadow (may work on iOS)
                </Text>
              </TouchableHighlight>
          </View>
          <View style={{ margin: 10, alignItems: 'center',
              justifyContent: 'center' }}>
              <TouchableHighlight style={{
                position: 'relative',
                width: 100,
                height: 100,
                backgroundColor: "#fff",
                borderRadius: 50,
                borderWidth: 1,
                borderColor: '#aaa',
                // marginVertical:5,
                alignItems: 'center',
                justifyContent: 'center',
                overflow: "hidden",
                elevation: 15,
               }}>
                <Text style={{ textAlign: 'center' }}>
                  3: vanilla RN: elevation only (15)
                </Text>
              </TouchableHighlight>
          </View>
        </View>

        <View style={{ flexDirection: 'row', justifyContent: 'center', marginBottom: 30 }}>
          <View style={{ margin: 10, alignItems: 'center',
              justifyContent: 'center' }}>
              <TouchableHighlight style={{
                position: 'relative',
                width: 100,
                height: 100,
                backgroundColor: "#fff",
                borderRadius: 50,
                borderWidth: 1,
                borderColor: '#aaa',
                // marginVertical:5,
                alignItems: 'center',
                justifyContent: 'center',
                overflow: "hidden",
                elevation: 5,
               }}>
                <Text style={{ textAlign: 'center' }}>
                  4: vanilla RN: elevation only (5)
                </Text>
              </TouchableHighlight>
          </View>
          <View style={{ margin: 10, alignItems: 'center',
              justifyContent: 'center' }}>
              <TouchableHighlight style={{
                position: 'relative',
                width: 100,
                height: 100,
                backgroundColor: "#fff",
                borderRadius: 50,
                borderWidth: 1,
                borderColor: '#aaa',
                // marginVertical:5,
                alignItems: 'center',
                justifyContent: 'center',
                overflow: "hidden",
                elevation: 50,
               }}>
                <Text style={{ textAlign: 'center' }}>
                  5: vanilla RN: elevation only (50)
                </Text>
              </TouchableHighlight>
          </View>
        </View>
      </View>
    )
  }
}

Upvotes: 2

Andrei Vedovato
Andrei Vedovato

Reputation: 171

Also i'd like to add that if one's trying to apply shadow in a TouchableHighlight Component in which child has borderRadius, the parent element (TouchableHighlight) also need the radius set in order to elevation prop work on Android.

Upvotes: 4

Kristijan Tomić
Kristijan Tomić

Reputation: 121

I had the same problem shadow/elevation not showing on Android with elevation:2. Then i noticed that the view element is fool width, so I added margin:2 to the view element and elevation properly appeared.

Style:

    margin: 2,
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 1
    },
    shadowOpacity: 0.2,
    shadowRadius: 1.41,
    elevation: 2

Android: enter image description here

iOS: enter image description here

Upvotes: 1

C-lio Garcia
C-lio Garcia

Reputation: 710

Set elevation: 3 and you should see the shadow in bottom of component without a 3rd party lib. At least in RN 0.57.4

Upvotes: 2

Muhammad Al Faris
Muhammad Al Faris

Reputation: 346

In short, you can't do that in android, because if you see the docs about shadow only Support IOS see doc

The best option you can install 3rd party react-native-shadow

Upvotes: 3

Kishan Vaghela
Kishan Vaghela

Reputation: 7938

I have implemented CardView for react-native with elevation, that support android(All version) and iOS. Let me know is it help you or not. https://github.com/Kishanjvaghela/react-native-cardview

import CardView from 'react-native-cardview'
<CardView
          cardElevation={2}
          cardMaxElevation={2}
          cornerRadius={5}>
          <Text>
              Elevation 0
          </Text>
</CardView>

enter image description here

Upvotes: 3

nlavr
nlavr

Reputation: 656

elevation still no work in Expo v30 && React-native v0.55.4. I have tried the all answers here.

Also, don't try react-native-shadow - their shadow rendering is terrible. So, I am continuing the research.

Upvotes: 1

Aras
Aras

Reputation: 1597

for an android screen you can use this property elevation.

for example :

 HeaderView:{
    backgroundColor:'#F8F8F8',
    justifyContent:'center',
    alignItems:'center',
    height:60,
    paddingTop:15,

    //Its for IOS
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.2,

    // its for android 
    elevation: 5,
    position:'relative',

},

Upvotes: 7

Mohammed Alawneh
Mohammed Alawneh

Reputation: 306

The following will help you to give each Platform the styling you want:

import { Text, View, Platform } from 'react-native';

......
<View style={styles.viewClass}></View>
......


const styles = {
viewClass: {
    justifyContent: 'center',
    alignItems: 'center',
    height: 60,
    ...Platform.select({
        ios: {
            shadowColor: '#000',
            shadowOffset: { width: 0, height: 2 },
            shadowOpacity: 0.2,
        },
        android: {
            elevation: 1

        },
      }),
}
};

Upvotes: 12

lam luu
lam luu

Reputation: 802

You can try

//ios    
shadowOpacity: 0.3,
shadowRadius: 3,
shadowOffset: {
    height: 0,
    width: 0
},
//android
elevation: 1

Upvotes: 48

SameerShaik
SameerShaik

Reputation: 526

Just use 'elevation' property to get shadow in android. something like below

const Header = () => {
    // const { textStyle, viewStyle } = styles;
    return (
      <View style={styles.viewStyle}>    
        <Text style={styles.textStyle}>Albums</Text>
      </View>
    )
}


const styles = {
    viewStyle:{
        backgroundColor:'#f8f8f8',
        justifyContext:'center',
        alignItems: 'center',
        padding:16,
        elevation: 2
    }
}

Upvotes: 5

Ajackster
Ajackster

Reputation: 1724

Another solution without using a third-party library is using elevation.

Pulled from react-native documentation. https://facebook.github.io/react-native/docs/view.html

(Android-only) Sets the elevation of a view, using Android's underlying elevation API. This adds a drop shadow to the item and affects z-order for overlapping views. Only supported on Android 5.0+, has no effect on earlier versions.

elevation will go into the style property and it can be implemented like so.

<View style={{ elevation: 2 }}>
    {children}
</View>

The higher the elevation, the bigger the shadow. Hope this helps!

Upvotes: 81

Related Questions