如何在React Native for Android中设置阴影?


72

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

这是我尝试过的

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

我需要达到的目标

在此处输入图片说明

Answers:


129

更新

添加CSS属性elevation: 1可在Android中渲染阴影,而无需安装任何第三方库-请参见其他答案。


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

6
添加css属性elevation: 1可在Android中渲染阴影,而无需安装任何第三方库。我使用React Native 0.52进行了测试
Guy

3
使用时要小心,elevation因为它不遵守您对的设置shadow,例如颜色和偏移量。
cseelus

这个lib,如果我不知道孩子指定的宽度高度怎么办。。。因为它要求。
Leang Socheat '18

@LeangSocheat你有没有想过,如果您事先不知道宽度或高度怎么办?我有同样的问题。谢谢。

有关react-native-shadow模块的@FuzzyTree似乎缺少主要内容。
胭脂红Tambascia

81

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

从本机文档中提取。 https://facebook.github.io/react-native/docs/view.html

(仅限Android)使用Android的基础海拔API设置视图的海拔。这将为项目添加阴影,并影响重叠视图的z顺序。仅在Android 5.0+上受支持,对早期版本无效。

elevation将进入该style属性,可以像这样实现。

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

海拔越高,阴影越大。希望这可以帮助!


为什么海拔属性写在2个花括号内?

7
@divine,外部括号用于JS插值,内部括号用于对象
Asaf David

4
这只会在视图的底部形成阴影,而不允许您在另一侧进行阴影
Erich

正确,iOS在使用react-native时可以处理很多事情,阴影就是其中之一。
Ajackster '17

1
不过要小心elevation-就像在文档中说的那样,它“影响重叠视图的Z顺序”-基本上就像a一样zIndex,您无法覆盖它,并且可能导致真正令人困惑的行为。例如,在带有粘性节标题的SectionList中,如果将其elevation: 3放在列表中,则它们会突然开始遍历标题,将它们从视图中隐藏(当然仅在android上)。这几乎是不可能调试的!
omn​​ikron

42

你可以试试

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

3
高程无法为Android创建足够大或可配置的阴影
-react

36

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

Android-如果没有backgroundColor,则高程样式属性将不起作用

例:

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

7
这真的需要更多的投票,我不知道为什么它不起作用
jsnid00'4

1
这就是我想要的。该解决方案适用于Android和iOS,而无需安装第三方库。
德拉利

1
这是我缺少的关键....这需要更多的upvotes
哈文德·辛格

11

以下内容将帮助您指定所需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

        },
      }),
}
};

4
无需指定平台,因为在iOS中高程属性将被忽略
Cody

3
@cody是的,你是对的!但我的示例显示了如何为不同平台设置样式。
Mohammed Alawneh '18

7

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

},

它可以正常工作,但是在Android中如何更改阴影颜色?
Jeremias Araujo,

5

只需使用“ 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
    }
}

5

我添加了borderBottomWidth:0,并且在android中对我来说效果很好。


5

您可以使用我的react-native-simple-shadow-view

  • 这使得Android中的阴影几乎与iOS中相同
  • 无需使用高程,可与iOS的相同阴影参数(shadowColor,shadowOpacity,shadowRadius,offset等)一起使用,因此您无需编写特定于平台的阴影样式
  • 可用于半透明视图
  • 在Android 18及更高版本中受支持

可以替换Animated.View吗?
穆罕默德Ğhøùdiï

试试:const AnimatedShadowView = Animated.createAnimatedComponent(ShadowView)。它应该可以工作
RoyBS '19


3

我还想补充一点,如果尝试在子项具有borderRadius的TouchableHighlight组件中应用阴影,则父元素(TouchableHighlight)也需要设置半径,以便在Android上进行高程支撑工作。



2

生成阴影的圆圈,反应原生,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>
    )
  }
}

1

在Expo v30 && React-native v0.55.4中,海拔高度仍然无效。我在这里尝试了所有答案。

另外,不要尝试react-native-shadow-它们的阴影渲染非常糟糕。因此,我正在继续研究。


1
谢谢。我想知道为什么海拔在世博会上不起作用。我的是SDK 32 :)
deadcoder0904

1

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


1

我在高程为2的Android上没有显示相同的阴影/高程问题。然后我注意到view元素的宽度很宽,因此我在view元素上添加了margin:2,并正确显示了高程。

风格:

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

Android: 在此处输入图片说明

iOS: 在此处输入图片说明


1

由于某种原因,它只能通过添加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,
      }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.