如何在React Native中将视图的背景色设置为透明


139

这是我使用过的视图样式

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

目前它具有白色背景。我可以根据需要更改backgroundColor,'#343434'但是它最多只能接受6个十六进制值作为颜色,所以我不能像上那样提供不透明度'#00ffffff'。我尝试使用这样的不透明度

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

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

Answers:


288

使用的rgbabackgroundColor

例如,

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

这会将其设置为不透明度为80%的灰色,该颜色由不透明度小数点得出0.8。该值可以是从0.0到的任何值1.0


为什么地球上的色值8位和Alpha值浮动?
duhaime

@duhaime,不确定具体为什么,但是从内存意义上(尤其是历史意义上),8位有意义。对于完全透明或完全不透明,alpha值的最小值和最大值分别为0和1更为有意义。例如,如果您希望某些东西具有25%的透明度,那么您就不想弄清楚255的1/4数是多少。
kojow7

104

以下工作正常:

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

您也可以尝试:

backgroundColor: 'transparent'

2
backgroundColor:到目前为止,“ transparent”是最简单的解决方案。
NathanL '18年

27

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


由于某种原因,此变体会错误地显示不透明的结果颜色。如果我没记错的话,那是RN中的错误。因此最好采用这种rgba方式。
Shyngys Kassymov,


@Oo有趣,这很有意义。感谢您指出!但是,IMO使用该rgba方法更容易:)
Shyngys Kassymov

这是否意味着该格式应改为#aarrggbb?
Shyngys Kassymov

我的意思是您可以在中使用六值rrggbbaa
Oo

3

您应该了解iOS和RGBA背景当前存在的冲突。

简介:公共React Native当前或多或少直接公开了iOS层阴影属性,但是这样做存在许多问题:

1)默认情况下,使用这些属性时的性能较差。这是因为iOS会通过获取视图的精确像素蒙版(包括任何半透明内容及其所有子视图)来计算阴影,这会占用大量CPU和GPU。2)iOS阴影属性与CSS框阴影标准的语法或语义不匹配,并且不太可能在Android上实现。3)我们不公开该layer.shadowPath属性,这对于从图层阴影中获得良好的性能至关重要。

此差异通过实现shadowPath与背景不透明的视图的视图边框匹配的默认值来解决问题1) 。通过针对常见使用情况进行优化,可以提高阴影的性能。我还为具有阴影道具的视图恢复了背景色传播-这应该有助于确保这种最佳情况发生的频率更高。

对于具有明显透明背景的视图,阴影将继续像以前一样工作(shadowPath将保持不变,并且阴影将完全从视图及其子视图的像素派生)。但是,这是性能的最坏情况,因此,除非绝对必要,否则应避免使用它。将来可能默认情况下禁用此功能,或者将其完全删除。

对于半透明图像,建议您将阴影烘焙到图像本身中,或者使用其他机制预先生成阴影。对于文本阴影,应该使用textShadow属性,该属性可以跨平台工作并且具有更好的性能。

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

问题3)现在几乎没有意义,因为我们会自动生成shadowPath。将来,如果需要对阴影进行更精确的控制,我们可能会提供特定于iOS的道具来显式设置路径。

评论者:weicool

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


2

令人惊讶的是,没有人告诉您这一点,它提供了一些明确的信息:

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

6
此解决方案不仅定义了整个视图的不透明性,还定义了整个视图的不透明性,从而导致其所有子级也变为半透明性(实际上是在原始问题中指出)
Cool Soft

-1

这是我对可以在任何屏幕上呈现并在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)
}

希望我能为您中的一些人提供帮助,我为应用内通知使用了非常相似的结构

快乐编码

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.