如何在 React Native 中设置透明视图的背景颜色
Posted
技术标签:
【中文标题】如何在 React Native 中设置透明视图的背景颜色【英文标题】:How to set background color of view transparent in React Native 【发布时间】:2015-09-28 22:55:10 【问题描述】:这是我使用的视图样式
backCover:
position: 'absolute',
marginTop: 20,
top: 0,
bottom: 0,
left: 0,
right: 0,
目前它有一个白色背景。我可以像'#343434'
一样更改背景颜色,但它只接受最多6 个十六进制值的颜色,所以我不能像'#00ffffff'
那样给出不透明度。我尝试使用这样的不透明度
backCover:
position: 'absolute',
marginTop: 20,
top: 0,
bottom: 0,
left: 0,
right: 0,
opacity: 0.5,
但它会降低视图内容的可见性。 那么有什么答案吗?
【问题讨论】:
【参考方案1】:如果您有十六进制颜色,您可以将其转换为 rgba 并在此处设置不透明度:
const hexToRgbA = (hex, opacity) =>
let c;
if (/^#([A-Fa-f0-9]3)1,2$/.test(hex))
c = hex.substring(1).split('');
if (c.length === 3)
c = [c[0], c[0], c[1], c[1], c[2], c[2]];
c = `0x$c.join('')`;
return `rgba($[(c >> 16) & 255, (c >> 8) & 255, c & 255].join(','),$opacity)`;
throw new Error('Bad Hex');
;
const color = '#1f8b7f'; // could be a variable
return (
<View style= backgroundColor: hexToRgbA(color, 0.1) />
)
source that helped me
【讨论】:
【参考方案2】:最好的使用方法是十六进制代码 rrggbbaa,但它应该是十六进制的。
例如:50% 不透明度意味着 256/2 然后将该值转换为 HEX 中的 80 所以使用 #00000080
80 意味着 50% 透明
【讨论】:
【参考方案3】:添加 React-Native 版本 0.64 的引用
命名颜色
Named Colors: DOCS在 React Native 中,您还可以使用颜色名称字符串作为值。 注意:React Native 只支持小写的颜色名称。不支持大写颜色名称。 透明# 这是 rgba(0,0,0,0) 的快捷方式,与 CSS3 中的一样。
因此你可以这样做:
background:
backgroundColor: 'transparent'
,
这是 : 的快捷方式
background:
backgroundColor: 'rgba(0,0,0,0)'
,
【讨论】:
【参考方案4】:尽量使用透明属性值来制作透明背景色。
backgroundColor: 'transparent'
【讨论】:
【参考方案5】:这是我对可以在任何屏幕上呈现并在 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)
希望我能对你们中的一些人有所帮助,我为应用内通知使用了非常相似的结构
快乐编码
【讨论】:
【参考方案6】:令人惊讶的是,没有人告诉过这件事,这提供了一些 !clarity:
style=
backgroundColor: 'white',
opacity: 0.7
【讨论】:
这个解决方案定义了整个视图的不透明度,而不仅仅是它的背景,导致它的所有子视图也变得半透明(实际上在原始问题中已经指出)【参考方案7】:您应该注意当前与 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 特定的 prop 来设置 如果需要更精确地控制 影子。
审核人:weicool
提交:https://github.com/facebook/react-native/commit/e4c53c28aea7e067e48f5c8c0100c7cafc031b06
【讨论】:
【参考方案8】:以下工作正常:
backgroundColor: 'rgba(52, 52, 52, alpha)'
你也可以试试:
backgroundColor: 'transparent'
【讨论】:
backgroundColor: 'transparent' 是迄今为止最简单的解决方案。【参考方案9】:试试这个backgroundColor: '#00000000'
它将背景颜色设置为透明,它遵循 #rrggbbaa 十六进制代码
【讨论】:
由于某种原因,此变体不正确地显示不透明的结果颜色。如果我没记错的话,那是 RN 中的一个错误。因此最好使用rgba
方式。
@ShyngysKassymov gist.github.com/lopspower/03fb1cc0ac9f32ef38f4 看看这个
@O.o 有趣,这是有道理的。感谢您指出!但是 IMO 更容易使用rgba
方式:)
是不是表示格式应该改为#aarrggbb?
我的意思是你可以在rrggbbaa
中使用十六进制值。【参考方案10】:
为backgroundColor
使用rgba
值。
例如,
backgroundColor: 'rgba(52, 52, 52, 0.8)'
这会将其设置为具有 80% 不透明度的灰色,这是从不透明度小数 0.8
派生的。该值可以是从0.0
到1.0
的任何值。
【讨论】:
为什么颜色值是 8 位而 alpha 值是浮动的? @duhaime,不知道具体为什么,但是从记忆的角度来看 8 位是有意义的(尤其是从历史上看)。对于完全透明或完全不透明,Alpha 值将 0 和 1 作为最小值和最大值更有意义。例如,如果您希望某物具有 25% 的透明性,您就不想弄清楚 255 的 1/4 是多少。以上是关于如何在 React Native 中设置透明视图的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章
React-native:如何在布局(视图)的背景中设置图像
是否可以在 React Native 中设置整个应用程序的背景? [复制]
如何在 React-Native 中设置 DrawerNavigator 的背景图片?