Cách đặt màu nền của chế độ xem trong suốt trong React Native


139

Đây là phong cách của quan điểm mà tôi đã sử dụng

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

Hiện tại nó có một nền trắng. Tôi có thể thay đổi màu nền như tôi muốn '#343434'nhưng nó chỉ chấp nhận tối đa 6 hexvalue cho màu để tôi không thể cung cấp độ mờ cho như thế '#00ffffff'. Tôi đã thử sử dụng opacity như thế này

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

nhưng nó làm giảm khả năng hiển thị nội dung của chế độ xem. Vậy câu trả lời nào?

Câu trả lời:


288

Sử dụng rgbagiá trị cho backgroundColor.

Ví dụ,

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

Điều này đặt nó thành một màu xám với độ mờ 80%, được lấy từ số thập phân độ mờ , 0.8. Giá trị này có thể là bất cứ điều gì từ 0.0đến 1.0.


Tại sao trên trái đất là các vals màu 8 bit và vals alpha nổi?
duhaime

@duhaime, không chắc tại sao cụ thể, nhưng 8 bit có ý nghĩa từ ý nghĩa bộ nhớ (đặc biệt là trong lịch sử). Các giá trị Alpha có ý nghĩa hơn khi có 0 và 1 là min và max cho hoàn toàn trong suốt hoặc mờ hoàn toàn. Ví dụ: nếu bạn muốn một cái gì đó trong suốt 25%, bạn không muốn tìm ra 1/4 của 255 là gì.
kojow7

104

Sau đây hoạt động tốt:

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

Bạn cũng có thể thử:

backgroundColor: 'transparent'

2
backgroundColor: 'trong suốt' là giải pháp đơn giản nhất.
NathanL

27

Hãy thử điều này, backgroundColor: '#00000000' nó sẽ đặt màu nền thành trong suốt, nó tuân theo mã hex #rrggbbaa


Vì một số lý do, biến thể này hiển thị màu kết quả với độ mờ không chính xác. Nếu tôi không nhầm thì đó là lỗi trong RN. Do đó tốt hơn để sử dụng rgbacách.
Shyngys Kassymov

1
@ShyngysKassymov gist.github.com/lopspower/03fb1cc0ac9f32ef38f4 kiểm tra điều này
Oo

@Oo thú vị, điều đó có ý nghĩa. Cảm ơn đã chỉ ra! Nhưng IMO thì dễ sử dụng rgbahơn :)
Shyngys Kassymov

điều đó có nghĩa là định dạng nên là #aarrggbb chứ?
Shyngys Kassymov

Tôi có nghĩa là bạn có thể sử dụng hexavalue trong rrggbbaa.
Oo

3

Bạn nên biết về các xung đột hiện tại tồn tại với nền iOS và RGBA.

Tóm tắt: công khai React Native hiện đang phơi bày các thuộc tính bóng của lớp iOS ít nhiều trực tiếp, tuy nhiên có một số vấn đề với điều này:

1) Hiệu suất khi sử dụng các thuộc tính này theo mặc định là kém. Đó là bởi vì iOS tính toán bóng bằng cách lấy mặt nạ pixel chính xác của chế độ xem, bao gồm mọi nội dung không rõ ràng và tất cả các bản xem xét của nó, rất tốn CPU và GPU. 2) Các thuộc tính bóng của iOS không khớp với cú pháp hoặc ngữ nghĩa của tiêu chuẩn bóng hộp CSS và không có khả năng thực hiện trên Android. 3) Chúng tôi không để lộ layer.shadowPathtài sản, điều rất quan trọng để có được hiệu suất tốt từ bóng lớp.

Khác biệt này giải quyết vấn đề số 1) bằng cách triển khai mặc định shadowPathkhớp với đường viền khung nhìn cho các khung nhìn với nền mờ. Điều này cải thiện hiệu suất của bóng bằng cách tối ưu hóa cho trường hợp sử dụng phổ biến. Tôi cũng đã khôi phục việc truyền màu nền cho các chế độ xem có đạo cụ bóng - điều này sẽ giúp đảm bảo rằng tình huống tốt nhất này xảy ra thường xuyên hơn.

Đối với các chế độ xem có nền trong suốt rõ ràng, bóng sẽ tiếp tục hoạt động như trước ( shadowPathsẽ không được đặt và bóng sẽ được lấy chính xác từ các pixel của chế độ xem và các lần xem trước của nó). Đây là con đường tồi tệ nhất cho hiệu suất, tuy nhiên, vì vậy bạn nên tránh nó trừ khi thực sự cần thiết. Hỗ trợ cho việc này có thể bị tắt theo mặc định trong tương lai hoặc bị loại bỏ hoàn toàn.

Đối với hình ảnh mờ, bạn nên nướng bóng vào hình ảnh hoặc sử dụng một cơ chế khác để tạo trước bóng. Đối với bóng văn bản, bạn nên sử dụng các thuộc tính textShadow, hoạt động đa nền tảng và có hiệu suất tốt hơn nhiều.

Vấn đề số 2) sẽ được giải quyết trong một khác biệt trong tương lai, có thể bằng cách đổi tên các thuộc tính ShadowXXX của iOS thành boxShadowXXX và thay đổi cú pháp và ngữ nghĩa để phù hợp với các tiêu chuẩn CSS.

Vấn đề số 3) bây giờ chủ yếu là tranh luận, vì chúng tôi tự động tạo ShadowPath. Trong tương lai, chúng tôi có thể cung cấp một chỗ dựa dành riêng cho iOS để đặt đường dẫn rõ ràng nếu có nhu cầu kiểm soát bóng chính xác hơn.

Được đánh giá bởi: weicool

Cam kết: https://github.com/facebook/react-native/commit/e4c53c28aea7e067e48f5c8c0100c7cafc031b06


2

Đáng ngạc nhiên không ai nói về điều này, trong đó cung cấp một số! Rõ ràng:

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

6
Giải pháp này xác định độ mờ cho toàn bộ khung nhìn, không chỉ nền của nó, khiến tất cả các con của nó cũng trở nên mờ đục (điều này thực sự được chỉ ra trong câu hỏi ban đầu)
Cool Soft

-1

Đây là giải pháp của tôi cho một phương thức có thể được hiển thị trên bất kỳ màn hình nào và được khởi tạo trong 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 kết xuất và nhập

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

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

và sử dụng nó từ bất kỳ thành phần nào

Một sốComponent.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)
}

Hy vọng tôi có thể giúp một số bạn, tôi đã sử dụng một cấu trúc rất giống nhau cho các thông báo trong ứng dụng

Chúc mừng mã hóa

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.