Як встановити прозорий колір подання прозорим у 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.


чому на Землі кольорові вали 8-бітні та альфа-вали плавають?
duhaime

@duhaime, не впевнений, чому конкретно, але 8-біт має сенс з пам’яті (особливо історично). Значення альфа мають більше сенсу мати 0 і 1 як min та max для повністю прозорих або повністю непрозорих. Наприклад, якщо ви хотіли, щоб щось було прозорим на 25%, ви не хочете розібратися, що таке 1/4 з 255.
kojow7

104

Наступне добре працює:

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

Ви також можете спробувати:

backgroundColor: 'transparent'

2
backgroundColor: "прозорий" - це найпростіше рішення.
NathanL

27

Спробуйте backgroundColor: '#00000000' це встановить колір фону прозорим, це відповідає шістнадцятковим кодам #rrggbbaa


Чомусь у цьому варіанті неправильно відображається результат кольору з непрозорістю. Якщо я не помиляюся, це помилка в RN. Тому краще використовувати rgbaспосіб.
Shyngys Kassmov

1
@ShyngysKassymov gist.github.com/lopspower/03fb1cc0ac9f32ef38f4 перевірити це
Oo

@Oo цікаво, що має сенс. Дякуємо, що вказали! Але ІМО простіше використовувати rgbaспосіб :)
Шингис Касимов

це означає, що замість цього формату має бути #aarrggbb?
Shyngys Kassmov

Я мав на увазі, що ви можете використовувати гексавальне значення в rrggbbaa.
Oo

3

Ви повинні бути в курсі поточних конфліктів, що існують із фоном 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 опору, щоб явно встановити шлях, якщо буде необхідний більш точний контроль тіні.

Оглянув: 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)
}

Сподіваюся, мені вдалося допомогти деяким із вас, я використовував дуже схожу структуру для сповіщень у додатках

Щасливе кодування

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.