React Native使用小结-1

无数次写样式的时候在心里吐槽,真的是“一夜回到解放前”!

主要的布局方式是flex

在css里不怎么使用,所以一开始非常不习惯,而且也觉得非常不自由。
不过只要记住justifyContent控制主轴,alignItems控制次轴,大部分情况都能handle。

position=”absolute”其实很方便

在css中,absolute的定位原点是position非static的最近的祖先元素,所以当我们想用absolute时,通常会在父元素的样式上添加position:"relative"
而在RN中,设置为absolute的元素默认以父组件为定位原点:

position in React Native is similar to regular CSS, but everything is set to relative by default, so absolute positioning is always just relative to the parent.

Image 和 border radius 的那些事

  1. Image作为背景时(也就是包含其他元素时),borderRadius会失效
    官方issue里有解决方案如下,可以试试:将borderRadius作为一个属性值传入Image组件

  2. 动图(包括gif和webp)的borderRadius会失效
    在stackoverflow上搜到一个解决方案:Rounded corner issue with GIF image in react native android

1
2
3
4
5
6
image: {
width: 75,
height: 75,
borderRadius: 10,
overlayColor: '#fff',
}

如上,在样式中使用overlayColor属性,官方文档的说明如下:

When the image has rounded corners, specifying an overlayColor will cause the remaining space in the corners to be filled with a solid color. This is useful in cases which are not supported by the Android implementation of rounded corners: - Certain resize modes, such as ‘contain’ - Animated GIFs

A typical way to use this prop is with images displayed on a solid background and setting the overlayColor to the same color as the background.

可以发现overlayColor就是用来填充图片的圆角,但是在使用中需要注意:

  1. 图片的背景需要是某种固定的颜色
  2. 图片不能有边框或者阴影

不过这个值并没有起到任何作用,最终的解决方案是 手动overlayColor
在目标图片上方添加一张overlayColor图,这张图需要符合下述条件:

  • 中心透明,用来展示图片
  • 可以画上边框或者阴影如果有需要
  • 四个边角的颜色需要与背景颜色保持一致(这也限制了背景需要为纯色)
    overlayColor图

附上代码:

1
2
3
4
5
6
7
8
9
10
11
render(){
return
<View style={baseStyle.item}>
<Image resizeMode="stretch"
style={baseStyle.itemImage}
source={{uri: this.itemImage}/>
<Image resizeMode="stretch"
style={baseStyle.imageMask}
source={{uri: this.imageMaskUri}/>
</View>
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const baseStyle = StyleSheet.create({
item: {
alignItems: 'center',
justifyContent: 'center',
width: 100,
height: 100,
elevation: 0, // 不能有阴影
borderRadius: 4,
borderWidth: 1,
borderColor: 'rgba(0,0,0,0.06)',
},
itemImage: {
width: 98,
height: 98,
borderRadius: 2.5,
},
imageMask: {
width: 98, //与itemImage保持一致
height: 98, //与itemImage保持一致
position: 'absolute',
top: 0,
left: 0,
},
});

Image在contain的时候,只能居中

resizeMode="contain"时,图片会默认在Image组件中居中,而且没有快捷的方法实现“contain”&&”左对齐/右对齐/其他任意位置”。(不像css里background那样方便)
如果需要实现上述效果,你需要:

  1. 手动将图片放在View或其他容器中
  2. 手动计算图片的宽高

在RN中实现一个三角形

和css中相同:

1
2
3
4
5
6
7
8
9
10
11
const styles=StyleSheet.create({
arrow:{
width:0,
height:0,
borderWidth:6,
borderTopColor:'#fff',
borderRightColor:'transparent',
borderBottomColor:'transparent',
borderLeftColor:'transparent',
}
})

在RN中会更加频繁地使用异步

调用本地方法时,经常会以异步的方式返回,所以跟普通的web应用比起来,需要处理更多异步方法。

循环动画

  1. 在start的回调函数里继续执行动画
  2. 一定要在componentWillUnmount时(或者之前)stopAnimation()
    具体见这个回答