React Nativeでビューの背景色を透明に設定する方法


139

これは私が使用したビューのスタイルです

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

現在、背景は白です。私は好きなようにbackgroundColorを変更できます'#343434'が、それは色に最大6 hexvalueしか受け入れないので、そのように不透明度を与えることはできません'#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)'

これにより、不透明度10進数から導出された80%の不透明度を持つ灰色に設定され0.8ます。この値には、0.0〜の任意の値を指定できます1.0


なぜ地球上でカラーバリューが8ビットでアルファバリューがフロートなのですか?
duhaime

@duhaime、特に具体的にはわかりませんが、8ビットはメモリの意味から(特に歴史的に)意味があります。アルファ値は、完全に透明または完全に不透明の最小値と最大値として0と1を持つ方がより意味があります。たとえば、25%の透明度が必要な場合、255の1/4が何であるかを理解する必要はありません。
kojow7

104

以下は正常に動作します:

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

あなたも試すことができます:

backgroundColor: 'transparent'

2
backgroundColor: 'transparent'は、最も簡単なソリューションです。
NathanL

27

これを試して backgroundColor: '#00000000' それは背景色を透明に設定します、それは#rrggbbaa 16進コードに従います


何らかの理由で、このバリアントは結果の色を不透明度で誤って表示します。私が間違っていなければ、それはRNのバグです。したがって、rgba方法を使用する方が良いです。
Shyngys Kassymov

1
@ShyngysKassymov gist.github.com/lopspower/03fb1cc0ac9f32ef38f4これをチェック
Oo

@Oo興味深いですね。指摘してくれてありがとう!しかしIMOの方が使いやすいrgba:)
Shyngys Kassymov

代わりに、形式を#aarrggbbにする必要がありますか?
Shyngys Kassymov

でヘキサ値を使用できることを意味しましたrrggbbaa
Oo

3

iOSおよびRGBAの背景に存在する現在の競合に注意する必要があります。

概要:public React Nativeは現在、iOSレイヤーのシャドープロパティを多かれ少なかれ直接公開していますが、これには多くの問題があります。

1)これらのプロパティを使用するときのパフォーマンスは、デフォルトでは不十分です。これは、iOSが、半透明コンテンツを含むビューの正確なピクセルマスクとそのすべてのサブビューを取得することによってシャドウを計算するためです。2)iOSシャドウプロパティは、CSSボックスシャドウ標準の構文またはセマンティクスと一致せず、Androidに実装することはできません。3)私たちは公開しませんlayer.shadowPathプロパティを。これは、レイヤーシャドウから良好なパフォーマンスを得るのに重要です。

このdiffは問題番号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)
}

私があなたの一部を助けることができたことを願って、私はアプリ内通知に非常に似た構造を使用しました

ハッピーコーディング

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.