React Native'de arka plan rengini saydam ayarlama


139

Kullandığım görünümün stili bu

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

Şu anda beyaz bir arka plan var. İstediğim gibi backgroundColor değiştirebilirim '#343434'ama renk için sadece maksimum 6 hexvalue kabul eder, bu yüzden bu gibi opaklık veremem '#00ffffff'. Böyle opaklık kullanmayı denedim

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

ancak görünüm içeriğinin görünürlüğünü azaltır. Yani cevaplar var mı?

Yanıtlar:


289

İçin rgbadeğeri kullanın backgroundColor.

Örneğin,

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

Bu, opaklık ondalıktan türetilen% 80 opaklığa sahip gri bir renge ayarlar 0.8. Bu değer herhangi bir şey olabilir 0.0için 1.0.


neden renk vals 8 bit ve alfa vals yüzer?
duhaime

@ duhaime, özellikle neden emin değilim, ancak 8 bit bellek anlamından mantıklı geliyor (özellikle tarihsel olarak). Alfa değerleri tamamen şeffaf veya tamamen opak için min ve maks olarak 0 ve 1'e sahip olmak daha mantıklıdır. Örneğin, bir şeyin% 25 şeffaf olmasını istiyorsanız, 255'in 1 / 4'ünün ne olduğunu bulmak istemezsiniz.
kojow7

104

Aşağıdaki iyi çalışır:

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

Ayrıca deneyebilirsiniz:

backgroundColor: 'transparent'

2
backgroundColor: 'şeffaf' açık ara en kolay çözümdür.
NathanL

27

Bunu deneyin backgroundColor: '#00000000' , arka plan rengini saydam olarak ayarlar, #rrggbbaa hex kodlarını izler


Bazı nedenlerden dolayı, bu değişken sonuç rengini opaklıkla yanlış görüntüler. Eğer yanılmıyorsam RN'de bir hata. Bu nedenle rgbayolu kullanmak daha iyidir .
Shyngys Kassymov

1
@ShyngysKassymov gist.github.com/lopspower/03fb1cc0ac9f32ef38f4 bunu kontrol edin
Oo

@ Çok ilginç, mantıklı. İşaret ettiğiniz için teşekkürler! Ama IMO rgbayolu kullanmak daha kolay :)
Shyngys Kassymov

biçimin #aarrggbb olması gerektiği anlamına mı geliyor?
Shyngys Kassymov

Yani onaltılık değeri kullanabilirsiniz rrggbbaa.
Oo

3

İOS ve RGBA arka planlarındaki mevcut çatışmaların farkında olmalısınız.

Özet: public React Native şu anda iOS katmanı gölge özelliklerini az çok doğrudan ortaya çıkarıyor, ancak bununla ilgili bir takım sorunlar var:

1) Bu özellikleri kullanırken performans varsayılan olarak düşüktür. Çünkü iOS gölgeyi, yarı saydam içerikler ve çok CPU ve GPU yoğun olan tüm alt görünümleri de dahil olmak üzere görünümün tam piksel maskesini alarak hesaplar. 2) iOS gölge özellikleri, CSS kutu-gölge standardının sözdizimi veya semantiğiyle eşleşmez ve Android'de uygulanması mümkün değildir. 3) layer.shadowPathKatman gölgelerinden iyi performans elde etmek için çok önemli olan özelliği göstermiyoruz.

Bu fark, shadowPathopak bir arka plana sahip görünümler için görünüm kenarlığına uyan bir varsayılan uygulayarak 1 numaralı sorunu çözer . Bu, yaygın kullanım durumu için optimize ederek gölgelerin performansını artırır. Ayrıca gölge sahne olan görünümler için arka plan renk yayılımını eski haline getirdim - bu, en iyi durum senaryosunun daha sık gerçekleşmesini sağlamalıdır.

Açık şeffaf arka plana sahip görünümler için, gölge daha önce olduğu gibi çalışmaya devam eder ( shadowPathayarlanmadan bırakılır ve gölge tam olarak görünümün piksellerinden ve alt görünümlerinden türetilir). Bu, performans için en kötü yoldur, bu nedenle kesinlikle gerekli olmadıkça bundan kaçınmalısınız. Bunun için destek gelecekte varsayılan olarak devre dışı bırakılabilir veya tamamen kaldırılabilir.

Yarı saydam görüntüler için, gölgeyi görüntünün kendisine pişirmeniz veya gölgeyi önceden oluşturmak için başka bir mekanizma kullanmanız önerilir. Metin gölgeleri için, platformlar arası çalışan ve çok daha iyi performansa sahip olan textShadow özelliklerini kullanmalısınız.

Sorun numarası 2), muhtemelen iOS shadowXXX özelliklerini boxShadowXXX olarak yeniden adlandırıp sözdizimi ve anlambilimini CSS standartlarına uyacak şekilde değiştirerek gelecekteki bir farkla çözülecektir.

Problem numarası 3) şimdi çoğunlukla tartışmalı, çünkü shadowPath'i otomatik olarak üretiyoruz. Gelecekte, gölgenin daha hassas bir şekilde kontrol edilmesine yönelik bir talep varsa, yolu açıkça ayarlamak için iOS'a özel bir destek sağlayabiliriz.

İnceleyen: weicool

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


2

Şaşırtıcı bir şekilde, hiç kimse bunu söylemedi, bu da bazı netlik sağlıyor:

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

6
Bu çözüm, yalnızca arka planına değil tüm görünüme opaklığı tanımlar ve tüm çocuklarının da yarı opak olmasına neden olur (aslında orijinal soruda belirtilir)
Cool Soft

-1

İşte herhangi bir ekranda oluşturulabilecek ve App.tsx içinde başlatılabilecek bir modsal çözümüm

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 oluşturma ve içe aktarma

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

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

ve herhangi bir bileşenden kullanma

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

Umarım bazılarınıza yardım edebildim, uygulama içi bildirimler için çok benzer bir yapı kullandım

Mutlu kodlama

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.