如何在 React Native 中为 android 设置阴影?

How to set shadows in React Native for android?

嗨,我正在尝试为我的工厂设置阴影,但到目前为止我的尝试都失败了,我尝试设置阴影道具,但这仅适用于 ios,所以我尝试使用 elevation 属性 但它看起来不对。

这是我试过的

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

我需要达到的目标

添加 CSS 属性 elevation: 1 在 Android 中渲染阴影而无需安装任何第 3 方库。

elevation 是 Android 的样式 属性,可用于 View 元素。

参见:React Native Docs for the elevation style property


如果您对第 3 方软件开放,另一种获取 android 阴影的方法是安装 react-native-shadow

示例(改编自自述文件):

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>
    );
  }
}

另一种不使用第三方库的解决方案是使用 elevation

取自 react-native 文档。 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 将进入 style 属性 并且可以这样实现。

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

海拔越高,影子越大。希望这对您有所帮助!

你可以试试

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

只需使用 'elevation' 属性 即可在 android 中获得阴影。类似下面

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
    }
}

对于 android 屏幕,您可以使用此 属性 elevation

例如:

 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',

},

以下内容将帮助您为每个 Platform 设置您想要的样式:

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

        },
      }),
}
};

elevation 在 Expo v30 && React-native v0.55.4 中仍然没有工作。 我已经尝试了这里的所有答案。

此外,不要尝试 react-native-shadow - 他们的阴影渲染很糟糕。 所以,我正在继续研究。

我已经实现了 CardView for react-native with elevation,它支持 android(所有版本)和 iOS。让我知道它是否对您有帮助。 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>

简而言之,您不能在 android 中执行此操作,因为如果您仅查看有关 shadow 的文档 支持 IOS see doc

您可以安装 3rd 方的最佳选择 react-native-shadow

设置elevation: 3,您应该会在没有第 3 方库的组件底部看到阴影。至少在 RN 0.57.4

我有同样的问题 shadow/elevation 没有在 Android 和 elevation:2 上显示。然后我注意到视图元素是傻瓜宽度,所以我将 margin:2 添加到视图元素并且正确显示了高度。

风格:

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

Android:

iOS:

我还想补充一点,如果有人试图在子元素具有 borderRadius 的 TouchableHighlight 组件中应用阴影,则父元素 (TouchableHighlight) 也需要设置半径才能在 Android.

为圆生成阴影,原生反应,android

根据这里的答案,以及我在 github (react-native-shadow) 中找到的文本,我做了一些测试,并认为有些人可能会发现以下内容有帮助。

屏幕如下所示:

代码:

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>
    )
  }
}

我添加了 borderBottomWidth: 0 它在 android.

中对我来说效果很好

你可以用我的react-native-simple-shadow-view

  • 这使得 Android 中的阴影与 iOS
  • 中几乎相同
  • 无需使用高度,使用与 iOS 相同的阴影参数(shadowColor、shadowOpacity、shadowRadius、offset 等),因此您无需编写平台特定的阴影样式
  • 可用于 semi-transparent 次观看
  • 支持 android 18 岁及以上

出于某种原因,它仅通过添加 borderColor: 'transparent'(或任何其他颜色)对我有效。我的样式输出如下所示:

{
        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,
      }

除非为元素指定 backgroundColor,否则 Android 上的 elevation 样式 属性 不起作用。

Android - elevation style property does not work without backgroundColor

示例:

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

这是一个简单的解决方案!

Click here to see preview of simple drop shadow

渲染折叠元素时不闪烁:

    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>
    );