So stellen Sie die Hintergrundfarbe der Ansicht in React Native transparent ein

139

Dies ist der Stil der Ansicht, die ich verwendet habe

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

Derzeit hat es einen weißen Hintergrund. Ich kann die Hintergrundfarbe nach '#343434'Belieben ändern, aber sie akzeptiert nur maximal 6 Hex-Werte für Farbe, sodass ich keine Deckkraft für diese Farbe geben kann '#00ffffff'. Ich habe versucht, diese Deckkraft so zu verwenden

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

Es verringert jedoch die Sichtbarkeit des Inhalts der Ansicht. Also irgendwelche Antworten?

JEROM FREUDE
quelle

Antworten:

288

Verwenden Sie den rgbaWert für die backgroundColor.

Beispielsweise,

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

Dies setzt es auf eine graue Farbe mit 80% Deckkraft, die von der Deckkraftdezimalzahl abgeleitet wird 0.8. Dieser Wert kann von 0.0bis sein 1.0.

dieuvn3b
quelle
Warum um alles in der Welt schweben Farbwerte 8 Bit und Alpha-Werte?
Duhaime
@duhaime, nicht sicher warum speziell, aber 8-Bit macht Sinn aus dem Gedächtnis Sinn (vor allem historisch). Alpha-Werte sind sinnvoller, wenn 0 und 1 als min und max für vollständig transparent oder vollständig undurchsichtig sind. Wenn Sie beispielsweise möchten, dass etwas zu 25% transparent ist, möchten Sie nicht herausfinden, was 1/4 von 255 ist.
kojow7
104

Folgendes funktioniert gut:

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

Sie könnten auch versuchen:

backgroundColor: 'transparent'
JEROM FREUDE
quelle
2
backgroundColor: 'transparent' ist bei weitem die einfachste Lösung.
NathanL
27

Versuchen Sie dies, backgroundColor: '#00000000' es setzt die Hintergrundfarbe auf transparent, es folgt #rrggbbaa Hex-Codes

Tharzeez
quelle
Aus irgendeinem Grund zeigt diese Variante die Ergebnisfarbe mit Deckkraft falsch an. Wenn ich mich nicht irre, ist es ein Fehler in RN. Deshalb besser den rgbaWeg benutzen .
Shyngys Kassymov
1
@ShyngysKassymov gist.github.com/lopspower/03fb1cc0ac9f32ef38f4 check this
Oo
@Oo interessant, das macht Sinn. Vielen Dank für den Hinweis! Aber IMO ist es einfacher, den rgbaWeg zu benutzen :)
Shyngys Kassymov
Bedeutet das, dass das Format stattdessen #aarrggbb sein sollte?
Shyngys Kassymov
Ich meinte, Sie können den Hexavalue in verwenden rrggbbaa.
Oo
3

Sie sollten sich der aktuellen Konflikte bewusst sein, die mit iOS- und RGBA-Hintergründen bestehen.

Zusammenfassung: public React Native macht die Schatteneigenschaften der iOS-Ebene derzeit mehr oder weniger direkt verfügbar. Hierbei gibt es jedoch eine Reihe von Problemen:

1) Die Leistung bei Verwendung dieser Eigenschaften ist standardmäßig schlecht. Dies liegt daran, dass iOS den Schatten berechnet, indem es die genaue Pixelmaske der Ansicht einschließlich aller durchscheinenden Inhalte und aller Unteransichten abruft, was sehr CPU- und GPU-intensiv ist. 2) Die iOS-Schatteneigenschaften stimmen nicht mit der Syntax oder Semantik des CSS-Box-Shadow-Standards überein und können wahrscheinlich nicht auf Android implementiert werden. 3) Wir legen die layer.shadowPathEigenschaft nicht frei, was entscheidend ist, um eine gute Leistung aus Schichtschatten zu erzielen.

Dieser Unterschied löst das Problem Nummer 1), indem ein Standard implementiert wird shadowPath, der dem Ansichtsrand für Ansichten mit einem undurchsichtigen Hintergrund entspricht. Dies verbessert die Leistung von Schatten durch Optimierung für den allgemeinen Anwendungsfall. Ich habe auch die Hintergrundfarbausbreitung für Ansichten mit Schattenrequisiten wiederhergestellt. Dies sollte sicherstellen, dass dieses Best-Case-Szenario häufiger auftritt.

Bei Ansichten mit einem expliziten transparenten Hintergrund funktioniert der Schatten weiterhin wie zuvor ( shadowPathwird nicht festgelegt und der Schatten wird genau aus den Pixeln der Ansicht und ihren Unteransichten abgeleitet). Dies ist jedoch der Worst-Case-Pfad für die Leistung. Sie sollten ihn daher vermeiden, sofern dies nicht unbedingt erforderlich ist. Die Unterstützung hierfür kann in Zukunft standardmäßig deaktiviert oder ganz eingestellt werden.

Für durchscheinende Bilder wird empfohlen, den Schatten in das Bild selbst zu backen oder einen anderen Mechanismus zu verwenden, um den Schatten vorab zu generieren. Für Textschatten sollten Sie die textShadow-Eigenschaften verwenden, die plattformübergreifend funktionieren und eine viel bessere Leistung aufweisen.

Problem Nummer 2) wird in einem zukünftigen Diff gelöst, möglicherweise durch Umbenennen der iOS-ShadowXXX-Eigenschaften in boxShadowXXX und Ändern der Syntax und Semantik, um den CSS-Standards zu entsprechen.

Problem Nummer 3) ist jetzt größtenteils umstritten, da wir den shadowPath automatisch generieren. In Zukunft werden wir möglicherweise eine iOS-spezifische Requisite bereitstellen, um den Pfad explizit festzulegen, wenn eine genauere Steuerung des Schattens erforderlich ist.

Bewertet von: weicool

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

Matías Gabel
quelle
2

Überraschenderweise hat niemand davon erzählt, was Klarheit schafft:

style={{
backgroundColor: 'white',
opacity: 0.7
}}
Antonin GAVREL
quelle
5
Diese Lösung definiert die Deckkraft für die gesamte Ansicht, nicht nur für den Hintergrund, was dazu führt, dass alle Kinder ebenfalls halb undurchsichtig werden (
Cool Soft,
-1

Hier ist meine Lösung für ein Modal, das auf jedem Bildschirm gerendert und in App.tsx initialisiert werden kann

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 rendern und importieren

import { ModalView } from './{your_path}/ModalComponent';

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

und es von jeder Komponente zu verwenden

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)
}

Ich hoffe, ich konnte einigen von Ihnen helfen. Ich habe eine sehr ähnliche Struktur für In-App-Benachrichtigungen verwendet

Viel Spaß beim Codieren

Nikola G. Tachev
quelle