【问题标题】:How do I render a shadow?如何渲染阴影?
【发布时间】:2015-06-02 03:08:02
【问题描述】:

如何在View 上渲染阴影?我尝试了shadowColorshadowOffsetshadowOpacityshadowRadius 的许多组合,但似乎无济于事。我确信样式应用正确,因为我设置了其他属性。

【问题讨论】:

标签: javascript react-native


【解决方案1】:

我使用的是 React-Native 0.40 及以下代码,适用于我在 IOS 和 Android 上。

(仅限 Android)使用 Android 的底层海拔 API 设置视图的海拔。这会为项目添加阴影并影响重叠视图的 z 顺序。仅在 Android 5.0+ 上支持,对早期版本没有影响。

 class MainApp extends Component {
  render() {
    return (
      <View style={styles.container}>

        <View elevation={5} style={styles.buttonContainer}>
          <Text style={styles.textStyle}>Shadow Applied</Text>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#FFFFFF'
  },
  textStyle: {
    color: '#FFFFFF'
  },
  buttonContainer: {
    backgroundColor: '#2E9298',
    borderRadius: 10,
    padding: 10,
    shadowColor: '#000000',
    shadowOffset: {
      width: 0,
      height: 3
    },
    shadowRadius: 5,
    shadowOpacity: 1.0
  }
})

在 iPhone 上测试。

编辑

来自@James 的评论。谢谢。

注意: 对于那些使用 android 的用户,背景颜色很重要。我使用 View 作为另一个元素的容器,在我指定背景颜色之前无法获得阴影。

【讨论】:

  • 对于安卓系统来说,背景颜色很关键。我使用 View 作为另一个元素的容器,在我指定背景颜色之前无法获得阴影。
  • @James 说了什么!!
  • 我在我的 cmets 中突出显示了答案。谢谢@james。
  • @James 背景颜色是我案例的答案!
【解决方案2】:

使用海拔在 RN Android 上实现阴影。 Added elevation prop #27

<View elevation={5}> </View>

【讨论】:

【解决方案3】:

根据CALayer docshadowOpacity 设置为类型 CGFloat 而不是 float 似乎是 React native 中的一个错误。在修复之前使用 iPhone 5 模拟器。 (CGFloat 在旧设备中是 float。)

正在跟踪的 React Native 问题是:

https://github.com/facebook/react-native/issues/449

【讨论】:

  • 如果您认为这是一个错误,请在bugreport.apple.com 提交雷达报告,并附上一个说明这一点的示例。
  • 刚刚在 iPhone 4s 模拟器中进行了测试,阴影效果很好 :)
【解决方案4】:
    viewStyle : {
    backgroundColor: '#F8F8F8',
    justifyContent: 'center',
    alignItems: 'center',
    height: 60,
    paddingTop: 15,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.2,
    marginBottom: 10,
    elevation: 2,
    position: 'relative'
},

使用marginBottom:10

【讨论】:

    【解决方案5】:

    你必须给 View 提供高程道具

    <View elevation={5} style={styles.container}>
       <Text>Hello World !</Text>
     </View>
    

    样式可以这样添加:

     const styles = StyleSheet.create({
    
         container:{
            padding:20,
            backgroundColor:'#d9d9d9',
            shadowColor: "#000000",
            shadowOpacity: 0.8,
            shadowRadius: 2,
            shadowOffset: {
              height: 1,
              width: 1
            }
           },
       })
    

    【讨论】:

      【解决方案6】:
        panel: {
          // ios
          backgroundColor: '#03A9F4',
          alignItems: 'center', 
          shadowOffset: {width: 0, height: 13}, 
          shadowOpacity: 0.3,
          shadowRadius: 6,
      
          // android (Android +5.0)
          elevation: 3,
        }
      

      或者你可以使用react-native-shadow 用于安卓

      【讨论】:

        【解决方案7】:

        关于边距

        这适用于Android,但没有在ios中测试过

        import React, { PureComponent } from 'react'
        import PropTypes from 'prop-types'
        import { View, Platform } from 'react-native'
        import EStyleSheet from 'react-native-extended-stylesheet'
        
        const styles = EStyleSheet.create({
            wrapper: {
                margin: '-1.4rem'
            },
            shadow: {
                padding: '1.4rem',
                margin: '1.4rem',
                borderRadius: 4,
                borderWidth: 0,
                borderColor: 'transparent',
                ...Platform.select({
                    ios: {
                        shadowColor: 'rgba(0,0,0, 0.4)',
                        shadowOffset: { height: 1, width: 1 },
                        shadowOpacity: 0.7,
                        shadowRadius: '1.4rem'
                    },
                    android: {
                        elevation: '1.4rem'
                    }
                })
            },
            container: {
                padding: 10,
                margin: '-1.4rem',
                borderRadius: 4,
                borderWidth: 0,
                borderColor: '#Fff',
                backgroundColor: '#fff'
            }
        })
        
        class ShadowWrapper extends PureComponent {
            static propTypes = {
                children: PropTypes.oneOfType([
                    PropTypes.element,
                    PropTypes.node,
                    PropTypes.arrayOf(PropTypes.element)
                ]).isRequired
            }
        
            render () {
                return (
                    View style={styles.wrapper}
                        View style={styles.shadow}
                            View style={styles.container}
                                {this.props.children}
                            View
                        View
                    View
                )
            }
        }
        
        export default ShadowWrapper
        

        【讨论】:

        • 将字符串值传递给海拔将出现类似于 Invalid prop elevation of type string 提供的错误。预期的“数字”
        • 这是因为:从 'react-native-extended-stylesheet' 导入 EStyleSheet
        【解决方案8】:

        按样式组件

        const StyledView = styled.View`
              border-width: 1;
              border-radius: 2;
              border-color: #ddd;
              border-bottom-width: 0;
              shadow-color: #000;
              shadow-offset: {width: 0, height: 2};
              shadow-opacity: 0.8;
              shadow-radius: 2;
              elevation: 1;     
        `
        

        或按样式

        const styles = StyleSheet.create({
          containerStyle: {
            borderWidth: 1,
            borderRadius: 2,
            borderColor: '#ddd',
            borderBottomWidth: 0,
            shadowColor: '#000',
            shadowOffset: { width: 0, height: 2 },
            shadowOpacity: 0.8,
            shadowRadius: 2,
            elevation: 1,
            marginLeft: 5,
            marginRight: 5,
            marginTop: 10,
          }
        })
        

        【讨论】:

        【解决方案9】:

        我正在使用样式化组件并为自己创建了一个辅助函数。

        它采用给定的 Android 高度并创建一个相当等效的 iOS 阴影。

        样式工具.js

        import { css } from 'styled-components/native';
        
        /*
         REMINDER!!!!!!!!!!!!!
         Shadows do not show up on iOS if `overflow: hidden` is used.
         https://react-native.canny.io/feature-requests/p/shadow-does-not-appear-if-overflow-hidden-is-set-on-ios
        */
        
        // eslint-disable-next-line import/prefer-default-export
        export const crossPlatformElevation = (elevation: number = 0) => css`
          /* Android - native default is 4, we're setting to 0 to match iOS. */
          elevation: ${elevation};
        
          /* iOS - default is no shadow. Only add if above zero */
          ${elevation > 0
            && css`
              shadow-color: black;
              shadow-offset: 0px ${0.5 * elevation}px;
              shadow-opacity: 0.3;
              shadow-radius: ${0.8 * elevation}px;
            `}
        `;
        

        使用

        import styled from 'styled-components/native';
        import { crossPlatformElevation } from "../../lib/stylingTools";
        
        export const ContentContainer = styled.View`
          background: white;
          ${crossPlatformElevation(10)};
        `;
        

        【讨论】:

          猜你喜欢
          • 2013-07-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-16
          • 2011-06-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多