背景
React Native 组件本身并不支持web开发中background-image
样式属性,而是采用背景图片组件ImageBackground
来实现背景图片的效果。因为项目开发需要,在使用ImageBackground
过程要要实现背景圆角border-radius
,发现官方没有提供ImageBackground
组件style
的文档,并且发现直接传递给style
属性的样式并不作用于背景组件本身。好奇之下,阅读了下该组件的源码,实现方式特别简单,但是有一个属性尤为重要:imageStyle
核心源码
class ImageBackground extends React.Component<$FlowFixMeProps> {
setNativeProps(props: Object) { ... }
...
render() {
const {children, style, imageStyle, imageRef, ...props} = this.props;
return (
<View style={style} ref={this._captureRef}>
<Image
{...props}
style={[
StyleSheet.absoluteFill,
{
// Temporary Workaround:
// Current (imperfect yet) implementation of <Image> overwrites width and height styles
// (which is not quite correct), and these styles conflict with explicitly set styles
// of <ImageBackground> and with our internal layout model here.
// So, we have to proxy/reapply these styles explicitly for actual <Image> component.
// This workaround should be removed after implementing proper support of
// intrinsic content size of the <Image>.
width: style.width,
height: style.height,
},
imageStyle,
]}
ref={imageRef}
/>
{children}
</View>
);
}
}
先看结构,
<View>
<Image></Image>
{children} // 这里的children可以是任意组件
</View>
ImageBackground
的实现方式:<View>
组件中包含一个<Image>
和任意其它组件,稍微提炼下:
<View style={style} ref={this._captureRef}>
<Image
{...props}
style={[
StyleSheet.absoluteFill,
{
width: style.width,
height: style.height,
},
imageStyle,
]}
ref={imageRef}
/>
{children}
</View>
传入的数据有children, style, imageStyle, imageRef
还有其它代表剩余属性值的...props
,可以看到,传入的style直接作用在<View>
组件上并不作用在<Image>
,children
是与<Image>
平级的子组件,imageStyle和其它属性值比如source直接传入Image
组件,这里的imageStyle
就是我们需要注意的,因为它接收的样式会作用于<Image>
,这里的StyleSheet.absoluteFill
来自于react-native/Libraries/StyleSheet/StyleSheet.js
const absoluteFillObject = {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
};
const absoluteFill = ReactNativePropRegistry.register(absoluteFillObject); // This also freezes it
这里的<Image>
是绝对定位,并且会填充整个<View>
扮演背景图片,也就是说imageStyle
就是背景图片的样式,然而,官方文档并未指明这样一个隐藏的重要属性。
例子
<ImageBackground
source={{url:".../profile" }}
style={{
width: 150,
height: 150,
justifyContent: "center",
alignItems: "center"
}}
>
<Text style={{ color: "white" }}>hello vincent</Text>
</ImageBackground>
预览
imageStyle={{
borderColor: "grey",
borderWidth: 2,
borderRadius: 75
}}
预览
谢谢~
网友评论