React Native 视觉还原小(da)技(shen)巧(keng)若干

2,494 阅读3分钟

画一条精细无比的实线

还记得一开始作为前端小萌新,被 0.5px 支配的恐惧吗?

“你这条线画的有问题,跟我视觉稿上不一样,看起来不够精致~”
“就一条线,咋不一样?咋不精致?”
“你这个粗了一点点!”
“哪有???我看不出来啊???”
“很明显啊!你再帮我调小 0.5 个像素。”
“。。。”

当年我们幸运 + 惊喜地发现 CSS 有伪元素、有 transform: scaleY(0.5),可以相对画出一条精确到小数点的线条时,才意识到:原来细微处还有这么多门门道道呵。

我在 React Native 中尝试了:

1.borderBottomWidth: 0.5
2.borderBottomWidth: 1; transform: [{scaleY: 0.5}]
3.height: 0.5
4.height: 1;transform: [{scaleY: 0.5}]

四种方式,结果都不尽如人意之后。我依旧没有选择狗带,下面这个方式通(逃)过了视觉妹子的火眼金睛。

123456789101112131415161718
import React from 'react';import {  View,  StyleSheet,  PixelRatio} from 'react-native';export default function UnderLine() {  return <View style={styles.underLine}></View>;}const styles = StyleSheet.create({  underLine: {    // 目前的最优解 Orz    height: 1 / PixelRatio.get(),    backgroundColor: '#DADFE6'  }});

画一条虚线(Dashed)

这个也许是一个相对挑(keng)战(die)过程了。

想当然,准备轻轻松松 borderStyle: 'dashed'; borderBottomWidth: 1???

怎么可能。

安卓对于 ‘dashed’ 支持可以说是惨不忍睹(IOS 我亲测也有问题),无法给元素单独一条边设置边框样式。

我的思路来自于 www.ctolib.com/mip/qfight-…

实现方式大同小异,都是用最原始方式,也就是一个个 View 元素,硬生生画出来。

不过我的方法支持横竖两种类型。

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
import React from 'react';import {  Text,  View,  StyleSheet,  Dimensions,} from 'react-native';const screenWidth = Dimensions.get('window').width;// dashScale(number): dash 每个点的规格/尺寸, // type(string): 水平/垂直类型,'row'/'column',// color[string]: 颜色, // height(number): 垂直模式下的高度export default function DashLine({ dashScale=6, type='row', color='#CED2D9', height=100 }) {  let len = type === 'row' ? Math.ceil(screenWidth / dashScale) : Math.ceil(height / dashScale);  let arr = [];  let computedStyle = {};  for(let i = 0; i < len; i++){    arr.push(i);  }  if (type === 'row') {    direction = 'row';    computedStyle = {      ...styles.dashItem,      backgroundColor: color    };  } else {    direction = 'column';    computedStyle = {      ...styles.dashItemCol,      backgroundColor: color    };  }  return <View style={{flexDirection: direction}}>    {      arr.map((item, index)=>{        return (          <Text            style={computedStyle}            key={'dash'+index}          />        );      })    }  </View>;}const styles = StyleSheet.create({  dashItem: {    transform: [{scaleY: 0.5}],    height: 1,    width: 2,    marginRight: 2,    flex: 1,    backgroundColor: '#CED2D9',  },  dashItemCol: {    transform: [{scaleX: 0.5}],    height: 2,    width: 1,    marginBottom: 2,    flex: 1,    backgroundColor: '#CED2D9',  }});

画阴影

RN 提供了阴影样式属性,但其仅支持 IOS 平台,在 Android 中需要:

  1. 需要设置 elevation 属性;
  2. color 只支持纯黑色 #000000;
  3. 如果 1 和 2 设置好了依旧在安卓不 work,请尝试为设置阴影的元素加上backgroundColor: #FFFFFF;

其他

  • 小心渲染一个列表时候,元素之间出现诡异的间隙
  • 事件响应元素层级不宜过深,安卓手机有兼容性问题

先到这儿。。。