【问题标题】:How to set background color of view transparent in React Native如何在 React Native 中设置透明视图的背景颜色
【发布时间】:2015-09-28 22:55:10
【问题描述】:

这是我使用的视图样式

backCover: {
  position: 'absolute',
  marginTop: 20,
  top: 0,
  bottom: 0,
  left: 0,
  right: 0,
}

目前它有一个白色背景。我可以像'#343434' 一样更改背景颜色,但它只接受最多6 个十六进制值的颜色,所以我不能像'#00ffffff' 那样给出不透明度。我尝试使用这样的不透明度

backCover: {
  position: 'absolute',
  marginTop: 20,
  top: 0,
  bottom: 0,
  left: 0,
  right: 0,
  opacity: 0.5,
}

但它会降低视图内容的可见性。 那么有什么答案吗?

【问题讨论】:

    标签: react-native


    【解决方案1】:

    如果您有十六进制颜色,您可以将其转换为 rgba 并在此处设置不透明度:

    const hexToRgbA = (hex, opacity) => {
      let c;
      if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)) {
        c = hex.substring(1).split('');
        if (c.length === 3) {
          c = [c[0], c[0], c[1], c[1], c[2], c[2]];
        }
        c = `0x${c.join('')}`;
        return `rgba(${[(c >> 16) & 255, (c >> 8) & 255, c & 255].join(',')},${opacity})`;
      }
      throw new Error('Bad Hex');
    };
    
    const color = '#1f8b7f'; // could be a variable
    
    return (
      <View style={{ backgroundColor: hexToRgbA(color, 0.1) }} />
    )
    

    source that helped me

    【讨论】:

      【解决方案2】:

      最好的使用方法是十六进制代码 rrggbbaa,但它应该是十六进制的。 例如:50% 不透明度意味着 256/2 然后将该值转换为 HEX 中的 80 所以使用 #00000080 80 意味着 50% 透明

      【讨论】:

        【解决方案3】:

        添加 React-Native 版本 0.64 的引用

        命名颜色

        在 React Native 中,您还可以使用颜色名称字符串作为值。 注意:React Native 只支持小写的颜色名称。不支持大写颜色名称。 透明# 这是 rgba(0,0,0,0) 的快捷方式,与 CSS3 中的一样。

        因此你可以这样做:

        background: {
            backgroundColor: 'transparent'        
        },
        

        这是 : 的快捷方式

        background: {
                backgroundColor: 'rgba(0,0,0,0)'            
            },
        

        【讨论】:

          【解决方案4】:

          尽量使用透明属性值来制作透明背景色。

          backgroundColor: 'transparent'
          

          【讨论】:

            【解决方案5】:

            这是我对可以在任何屏幕上呈现并在 App.tsx 中初始化的模式的解决方案

            ModalComponent.tsx

            import React, { Component } from 'react';
            import { Modal, Text, TouchableHighlight, View, StyleSheet, Platform } from 'react-native';
            import EventEmitter from 'events';
            // I keep localization files for strings and device metrics like height and width which are used for styling 
            import strings from '../../config/strings';
            import metrics from '../../config/metrics';
            
            const emitter = new EventEmitter();
            export const _modalEmitter = emitter
            
            export class ModalView extends Component {
                state: {
                    modalVisible: boolean,
                    text: string, 
                    callbackSubmit: any, 
                    callbackCancel: any,
                    animation: any
                }
            
                constructor(props) {
                    super(props)
                    this.state = {
                        modalVisible: false,
                        text: "", 
                        callbackSubmit: (() => {}), 
                        callbackCancel: (() => {}),
                        animation: new Animated.Value(0)
                    } 
                }
            
                componentDidMount() {
                    _modalEmitter.addListener(strings.modalOpen, (event) => {
                        var state = {
                            modalVisible: true,
                            text: event.text, 
                            callbackSubmit: event.onSubmit, 
                            callbackCancel: event.onClose,
                            animation: new Animated.Value(0)
                        } 
                        this.setState(state)
                    })
                    _modalEmitter.addListener(strings.modalClose, (event) => {
                        var state = {
                            modalVisible: false,
                            text: "", 
                            callbackSubmit: (() => {}), 
                            callbackCancel: (() => {}),
                            animation: new Animated.Value(0)
                        } 
                        this.setState(state)
                    })
                }
            
                componentWillUnmount() {
                    var state = {
                        modalVisible: false,
                        text: "", 
                        callbackSubmit: (() => {}), 
                        callbackCancel: (() => {})
                    } 
                    this.setState(state)
                }
            
                closeModal = () => {
                    _modalEmitter.emit(strings.modalClose)
                }
            
                startAnimation=()=>{
                    Animated.timing(this.state.animation, {
                        toValue : 0.5,
                        duration : 500
                    }).start()
                }
            
                body = () => {
                    const animatedOpacity ={
                        opacity : this.state.animation
                    }
                    this.startAnimation()
                    return (
                        <View style={{ height: 0 }}>
                            <Modal
                                animationType="fade"
                                transparent={true}
                                visible={this.state.modalVisible}>
            
                                // render a transparent gray background over the whole screen and animate it to fade in, touchable opacity to close modal on click out
            
                                <Animated.View style={[styles.modalBackground, animatedOpacity]} > 
                                    <TouchableOpacity onPress={() => this.closeModal()} activeOpacity={1} style={[styles.modalBackground, {opacity: 1} ]} > 
                                    </TouchableOpacity>
                                </Animated.View>
            
                                // render an absolutely positioned modal component over that background
                                <View style={styles.modalContent}>
            
                                    <View key="text_container">
                                        <Text>{this.state.text}?</Text>
                                    </View>
                                    <View key="options_container">
                                        // keep in mind the content styling is very minimal for this example, you can put in your own component here or style and make it behave as you wish
                                        <TouchableOpacity
                                            onPress={() => {
                                                this.state.callbackSubmit();
                                            }}>
                                            <Text>Confirm</Text>
                                        </TouchableOpacity>
            
                                        <TouchableOpacity
                                            onPress={() => {
                                                this.state.callbackCancel();
                                            }}>
                                            <Text>Cancel</Text>
                                        </TouchableOpacity>
            
                                    </View>
                                </View>
                            </Modal>
                        </View> 
                    );
                }
            
                render() {
                    return this.body()
                }
            }
            
            // to center the modal on your screen 
            // top: metrics.DEVICE_HEIGHT/2 positions the top of the modal at the center of your screen
            // however you wanna consider your modal's height and subtract half of that so that the 
            // center of the modal is centered not the top, additionally for 'ios' taking into consideration
            // the 20px top bunny ears offset hence - (Platform.OS == 'ios'? 120 : 100)
            // where 100 is half of the modal's height of 200
            const styles = StyleSheet.create({
                modalBackground: {
                    height: '100%', 
                    width: '100%', 
                    backgroundColor: 'gray', 
                    zIndex: -1 
                },
                modalContent: { 
                    position: 'absolute', 
                    alignSelf: 'center', 
                    zIndex: 1, 
                    top: metrics.DEVICE_HEIGHT/2 - (Platform.OS == 'ios'? 120 : 100), 
                    justifyContent: 'center', 
                    alignItems: 'center', 
                    display: 'flex', 
                    height: 200, 
                    width: '80%', 
                    borderRadius: 27,
                    backgroundColor: 'white', 
                    opacity: 1 
                },
            })
            

            App.tsx 渲染和导入

            import { ModalView } from './{your_path}/ModalComponent';
            
            render() {
                return (
                    <React.Fragment>
                        <StatusBar barStyle={'dark-content'} />
                        <AppRouter />
                        <ModalView />
                    </React.Fragment>
                )
            }
            

            并从任何组件中使用它

            SomeComponent.tsx

            import { _modalEmitter } from './{your_path}/ModalComponent'
            
            // Some functions within your component
            
            showModal(modalText, callbackOnSubmit, callbackOnClose) {
                _modalEmitter.emit(strings.modalOpen, { text: modalText, onSubmit: callbackOnSubmit.bind(this), onClose: callbackOnClose.bind(this) })
            }
            
            closeModal() {
                _modalEmitter.emit(strings.modalClose)
            }
            

            希望我能对你们中的一些人有所帮助,我为应用内通知使用了非常相似的结构

            快乐编码

            【讨论】:

              【解决方案6】:

              令人惊讶的是,没有人告诉过这件事,这提供了一些 !clarity:

              style={{
              backgroundColor: 'white',
              opacity: 0.7
              }}
              

              【讨论】:

              • 这个解决方案定义了整个视图的不透明度,而不仅仅是它的背景,导致它的所有子视图也变得半透明(实际上在原始问题中已经指出)
              【解决方案7】:

              您应该注意当前与 iOS 和 RGBA 背景存在的冲突。

              总结:public React Native 目前暴露了 iOS 层阴影 属性或多或少直接,但是有一些 这个问题:

              1) 默认情况下使用这些属性时的性能很差。那是 因为iOS通过获取精确的像素掩码来计算阴影 视图,包括任何半透明内容,及其所有子视图, 这是非常CPU和GPU密集型的。 2)iOS阴影属性做 与 CSS box-shadow 标准的语法或语义不匹配,并且 不太可能在Android上实现。 3)我们不 公开layer.shadowPath 属性,这对于获取 图层阴影表现良好。

              这个差异通过实现默认值解决了问题 1) shadowPath 匹配不透明视图的视图边框 背景。这通过优化 常见的使用案例。我还恢复了背景颜色 传播具有阴影道具的视图 - 这应该会有所帮助 确保这种最佳情况更频繁地发生。

              对于具有显式透明背景的视图,阴影将 继续像以前一样工作(shadowPath 将保持未设置, 并且阴影将完全来自视图的像素,并且 它的子视图)。然而,这是性能最差的路径, 所以除非绝对必要,否则你应该避免它。 对此的支持 将来可能会默认禁用,或完全放弃。

              对于半透明的图像,建议您将阴影烘焙到 图像本身,或使用另一种机制来预生成阴影。 对于文本阴影,您应该使用 textShadow 属性,该属性有效 跨平台并具有更好的性能。

              问题 2) 将在未来的差异中解决,可能通过 将 iOS shadowXXX 属性重命名为 boxShadowXXX,并更改 符合 CSS 标准的语法和语义。

              问题 3) 现在基本上没有实际意义,因为我们生成了 shadowPath 自动地。将来,我们可能会提供一个 iOS 特定的 prop 来设置 如果需要更精确地控制 影子。

              审核人:weicool

              提交:https://github.com/facebook/react-native/commit/e4c53c28aea7e067e48f5c8c0100c7cafc031b06

              【讨论】:

                【解决方案8】:

                以下工作正常:

                backgroundColor: 'rgba(52, 52, 52, alpha)'
                

                你也可以试试:

                backgroundColor: 'transparent'
                

                【讨论】:

                • backgroundColor: 'transparent' 是迄今为止最简单的解决方案。
                【解决方案9】:

                试试这个backgroundColor: '#00000000' 它将背景颜色设置为透明,它遵循 #rrggbbaa 十六进制代码

                【讨论】:

                • 由于某种原因,此变体不正确地显示不透明的结果颜色。如果我没记错的话,那是 RN 中的一个错误。因此最好使用rgba方式。
                • @ShyngysKassymov gist.github.com/lopspower/03fb1cc0ac9f32ef38f4 看看这个
                • @O.o 有趣,这是有道理的。感谢您指出!但是 IMO 更容易使用rgba 方式:)
                • 是不是表示格式应该改为#aarrggbb?
                • 我的意思是你可以在rrggbbaa中使用十六进制值。
                【解决方案10】:

                backgroundColor 使用rgba 值。

                例如,

                backgroundColor: 'rgba(52, 52, 52, 0.8)'
                

                这会将其设置为具有 80% 不透明度的灰色,这是从不透明度小数 0.8 派生的。该值可以是从0.01.0 的任何值。

                【讨论】:

                • 为什么颜色值是 8 位而 alpha 值是浮动的?
                • @duhaime,不知道具体为什么,但是从记忆的角度来看 8 位是有意义的(尤其是从历史上看)。对于完全透明或完全不透明,Alpha 值将 0 和 1 作为最小值和最大值更有意义。例如,如果您希望某物具有 25% 的透明性,您就不想弄清楚 255 的 1/4 是多少。
                猜你喜欢
                • 2016-01-31
                • 2011-04-14
                • 1970-01-01
                • 2015-07-10
                • 2011-06-26
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-03-03
                相关资源
                最近更新 更多