Как установить прозрачный цвет фона в 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,
}

но это уменьшает видимость содержимого представления. Так есть ответы?

Джером Радость
источник

Ответы:

288

Используйте rgbaзначение для backgroundColor.

Например,

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

Это устанавливает его в серый цвет с 80% непрозрачностью, который является производной от непрозрачности десятичного 0.8. Это значение может быть любым от 0.0до 1.0.

dieuvn3b
источник
с какой стати цвета 8-битные и альфа-значения плавают?
Духайме
@duhaime, не уверен, почему конкретно, но 8-битный имеет смысл с точки зрения памяти (особенно исторически). Альфа-значения имеют больше смысла, чтобы иметь 0 и 1 в качестве минимального и максимального значения для полностью прозрачного или полностью непрозрачного. Например, если вы хотите, чтобы что-то было прозрачным на 25%, вы не хотите выяснять, что такое 1/4 из 255.
kojow7
104

Следующее работает отлично:

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

Вы также можете попробовать:

backgroundColor: 'transparent'
Джером Радость
источник
2
backgroundColor: «прозрачный» - безусловно, самое простое решение.
NathanL
27

Попробуйте это, backgroundColor: '#00000000' он установит прозрачный цвет фона, это следует за шестнадцатеричными кодами #rrggbbaa

Tharzeez
источник
По какой-то причине этот вариант отображает цвет результата с непрозрачностью неправильно. Если я не ошибаюсь, это ошибка в RN. Поэтому лучше использовать rgbaспособ.
Шынгыс Касымов
1
@ShyngysKassymov gist.github.com/lopspower/03fb1cc0ac9f32ef38f4 проверить это
Оо
@ Интересно, это имеет смысл. Спасибо за указание! Но ИМО проще использовать rgbaспособом :)
Шынгыс Касымов
это означает, что формат должен быть #aarrggbb вместо этого?
Шынгыс Касымов
Я имел в виду, что вы можете использовать hexavalue в rrggbbaa.
Оо
3

Вы должны знать о текущих конфликтах, которые существуют с фонами iOS и RGBA.

Описание: public React Native в настоящее время более или менее напрямую раскрывает свойства тени слоя iOS, однако есть ряд проблем с этим:

1) Производительность при использовании этих свойств по умолчанию низкая. Это связано с тем, что iOS рассчитывает тень, получая точную пиксельную маску вида, включая любой полупрозрачный контент и все его подпредставления, которые сильно нагружают ЦП и ГП. 2) Свойства тени iOS не соответствуют синтаксису или семантике стандарта CSS box-shadow и вряд ли будут реализованы на Android. 3) Мы не раскрываем layer.shadowPathсвойство, которое имеет решающее значение для получения хорошей производительности от теней слоев.

Эта разница решает проблему номер 1) путем реализации значения по умолчанию, shadowPathкоторое соответствует границе представления для представлений с непрозрачным фоном. Это повышает производительность теней за счет оптимизации для общего случая использования. Я также восстановил распространение цвета фона для представлений, которые имеют теневые опоры - это должно помочь гарантировать, что этот лучший сценарий встречается чаще.

Для представлений с явным прозрачным фоном тень будет продолжать работать так же, как и раньше ( 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)
}

Надеюсь, я смог помочь некоторым из вас, я использовал очень похожую структуру для уведомлений в приложении

Удачного кодирования

Никола Г. Тачев
источник