React-Native采坑总结

摘要:
1.zIndex 在Android上使用zIndex来控制组件的层级,会遇到元素不显示的问题。解决方案: 尽量改变组件的顺序,而不用zIndex 尽量不要使用zIndex来控制组件的层级,默认情况下,使用position: 'absolute'后,后面的元素会默认覆盖在前面的元素之上。所以删除zIndex,改变一下组件的顺序就OK啦。 issues: https://github.com/facebook/react-native/issues/8968 

1.zIndex

在Android上使用zIndex来控制组件的层级,会遇到元素不显示的问题。
解决方案:
尽量改变组件的顺序,而不用zIndex
尽量不要使用zIndex来控制组件的层级,默认情况下,使用position: 'absolute'后,后面的元素会默认覆盖在前面的元素之上。所以删除zIndex,改变一下组件的顺序就OK啦。
issues: https://github.com/facebook/react-native/issues/8968 

2.borderStyle:'dashed'

目前,Android上,如果想要实现一条水平方向的虚线,一开始想到的肯定是:

border: {
  borderColor: 'red',
  borderWidth: 0,
  borderBottomWidth: 1,
  borderStyle: 'dashed'
}

但是实际上,这样是不会生效的,目前Android还不支持某一边设置虚线。
解决方案:
方案一:假设我们想要一个线宽为h的水平虚线,设置一个高度为h的view,里面给一个view设置四边都是dashed的边框,borderWidth为h,高度为0,然后外层设置overflow: 'hidden'但是,你会发现,不管你怎么overflow,都是没用的,Android照样会渲染出两个边框,看起来overflow也没有起作用。
方案二:换一种思路,再弄一个view,高度为h,背景颜色设置成你想要的颜色,然后把下面的border覆盖掉。
此外,也可以关注下这个issue: Border is invisible when using borderStyle='dashed' with borderBottom #7838

3.TouchableOpacity等可点击组件,有时候点击不触发onPress

这个问题,如果你只是在代码里面放了类似下面的代码:

<TouchableOpacity 
    style={styles.btn}onPress={this.onPress.bind(this)}>
  <Text>立即预定</Text>
</TouchableOpacity>

并且onPress回调里面,并没有做太多的逻辑,或者导致重新渲染。
那么,你没有必要怀疑是你代码的问题。RN对部分国产手机那些自定义的手势支持不好。

4.[style]Android上Text默认的字体颜色,不是black,不是black,不是black

如果在Android上面,不显示地给Text添加color,那么显示出来的字体颜色就是灰色。跟iOS的表现不一致;
解决方案:
方案一:给每个Text都设置color

不足:每次都设置color。比较繁琐

方案二:写一个自定义组件

比如MyText,这个Text设置颜色,每次使用xxx就默认为你设置的颜色了。
不足:多出来了一个新的组件,也比较繁琐。
多出来了一个新的组件,也比较繁琐。

方案三:设置默认props

在入口文件里面写上默认的style,比如:
Text.defaultProps.sytle = { 'color': '#212121'}

5.[ListView] renderRow 使用 this.state.xxx 属性,setState({xxx:'xxx'})的时候 ListView没有重新渲染

解决方案 重新设置 ListView 的 dataSource

6.[console] console.log()打印出来的对象,值不是最准确的,可能会受后面执行代码的影响。

7.[网络请求] 安卓机型连代理,有时抓不到请求

RN-andriod 用的网络模块是okhttp。这个模块有一个类似代理路由的功能。通过代理(比如charles)发送一个请求时,如果该请求timeout或者error了(比如abort),okhttp在下次发送请求时可能不走charles。导致请求发出去了,但是charles抓不到。

8.[ios模拟器] 配置localhost:port之后,请求不到js

如果没有提示说服务没有启动,提示404。基本上就是你电脑上没有配置localhost对应的host。可能有写hosts工具切换的时候,把localhost弄掉了。自己加回来:

127.0.0.1 localhost

9.RN0.46以上版本,使用touchable视图包裹TextInput组件,touchable视图上的onPress事件不能触发

<TouchableOpacity>
    <TextInput />     <---- touch not working here
    <Text>Text</Text>      <---- touch working here
</TouchableOpacity>

这个属于官方未修复的问题,详见https://github.com/facebook/react-native/issues/14958
临时解决方案
TextInput包裹在一个View中,给这个视图的pointEvents的属性设置为none

<TouchableOpacity
onPress={()=>{console.log('press')}}>
   <View pointerEvents='none'>
      <TextInput editable={false} />
   </View>
</TouchableOpacity>

10.TextInput问题

TextInput在安卓上默认有一个底边框,同时会有一些padding。如果要想使其看起来和iOS上尽量一致,则需要设置padding: 0,同时设置underlineColorAndroid="transparent"来去掉底边框。

11.内容对齐问题

新增的展示内容与原有的结构往往不同,上下对齐需要通过margin和padding来调整。以下是调整中遇到的问题及解决:

1.ios和adr的表现不一致,测试时需要两种机型都看下,在style中根据platform分别调整数值。

2.开发完后可能肉眼看觉得ok,但ui那边是通过画线验收,如上图所示。所以我们最好完了也用线对齐看看,减少修改的次数。

3.一行文字中同时存在汉字、数字、特殊符号时,它们有时不会底对齐,又或者ui要求垂直居中。这个可以通过lineHeight和paddingTop来调整。

4.必要时会用到0点几这种数值。

5.一行字里有文字有数字不对齐这种,也可以换个字体解决哈~ Helvetica Verdana Cochin 都可以。

12.RN中组件阴影解决方案

不知从什么时候开始,公司的UI偏爱给所有模块加上阴影效果,对于IOS系统,RN支持通过style设置阴影,但是Android系统着实让人头痛,在实践过程中先后使用过多种方法。

<View elevation={5} style={styles.container}>
   <Text>Hello World !</Text>
 </View>
  • IOS阴影实现方案

RN在ios系统上支持一系列阴影的样式属性,但这些属性在Andriod上不会生效。

container : {
    shadowColor: '#000',
    shadowOffset: {  0, height: 2 },
    shadowRadius: 2,
    shadowOpacity: 0.2
}
  • Android阴影实现方案

(1)使用elevation属性

<View elevation={2} style={styles.container}>
   <Text>Hello World !</Text>
</Vie
container : {
    shadowColor: '#000',
    shadowOffset: {  0, height: 2 },
    shadowRadius: 2,
    shadowOpacity: 0.2,
    elevation: 2
}

这个属性可以写在样式里也可以直接当做组件的属性,使用这个属性可以产生一定的阴影效果,但是阴影颜色、透明度等都不能定制,大多数情况下并不满足UI的要求。

(2)使用Image组件做背景

<Image style={styles.bgImg} source={{uri:bgImg}} resizeMode="stretch">
    <YourView />
</Image>

或者

<View>
    <Image style={styles.bgImg} source={{uri:bgImg}} resizeMode="stretch" />
    <YourView />
</View>

设置Image的样式未绝对定位铺满容器,类似于下面的ImageBackground,RN0.46.4加入了一个组件ImageBackground,可以像上面类似的方式使用.源码非常简单,https://github.com/facebook/react-native/blob/master/Libraries/Image/ImageBackground.js

'use strict';
const Image = require('Image');
const React = require('React');
const StyleSheet = require('StyleSheet');
const View = require('View');
const ensureComponentIsNative = require('ensureComponentIsNative');
import type {NativeMethodsMixinType} from 'ReactNativeTypes';

class ImageBackground extends React.Component {
  setNativeProps(props: Object) {
    // Work-around flow
    const viewRef = this._viewRef;
    if (viewRef) {
      ensureComponentIsNative(viewRef);
      viewRef.setNativeProps(props);
    }
  }

  _viewRef: ?NativeMethodsMixinType = null;

  _captureRef = ref => {
    this._viewRef = ref;
  };

  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>.
               style.width,
              height: style.height,
            },
            imageStyle,
          ]}
          ref={imageRef}
        />
        {children}
      </View>
    );
  }
}

module.exports = ImageBackground;

类似这种使用图片都阴影背景的方式,一般设置里面内容的背景色为透明色,在实践过程中有时会出现背景图片还未加载完成,但里面的内容已加载完成的情况,会出现背景的一个跳变。

<Image style={styles.bgImg} source={{uri:bgImg}} resizeMode="stretch">
    <View style={[styles.bg,StyleSheet.absoluteFill]}></View>
    <YourView/>
</Image>

目前我采用的方案是使用一个单独的View垫底,较好的解决了这个问题。但是图片拉伸变形的问题估计没有好的解决方案了。

(3).使用“点9图(.9图)”封装一个Native组件
Android系统支持一个牛叉的东西叫“点9图”,以前真没听过,估计原生开发知道这个东西,它有一个特点是拉伸后不会变形,包括圆角。关于点9图的概念可以参考.9.PNG是啥?.关于如何原生封装一个带有点9图背景的组件,我也不知道啊,这部分是原生开发实现的。参考React Native显示点9图片,也许有帮助,现在我们业务线都是使用这种方式,效果比较好。

免责声明:文章转载自《React-Native采坑总结》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇webDriver运行过程中遇到的问题bat脚本以管理员身份运行时,目录没有定位到当前目录问题的解决方法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python学习——re模块

re模块 findall***** 返回列表,找所有的匹配结果 语法:findall('正则表达式','待匹配字符串',flag) search***** 返回一个内存地址,这是一个正则匹配的结果span是索引,match是匹配结果,通过group取值;没有对应匹配结果就返回None,group会报错 语法:search(‘正则表达式’,‘待匹配字符串...

UUID生成唯一的16位随机数

* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. package java.util; import java.security.*; /** * A class that represents an immutable universal...

php发送get、post请求的几种方法

方法1: 用file_get_contents 以get方式获取内容 1 <?php 2 $url='http://www.domain.com/'; 3 $html = file_get_contents($url); 4 echo $html; 5 ?> 方法2: 用fopen打开url, 以get方式获取内容 1 &l...

前端嵌入视频直播和聊天支持.m3u8格式

1、安装vue-video-player npm install vue-video-player --save 2、在main.js中引入vue-video-player import VideoPlayer from 'vue-video-player' require('video.js/dist/video-js.css') require('vu...

vue 点击显示隐藏,鼠标移动上去显示隐藏

1,鼠标点击显示隐藏,样式可以自己调,我就写个dome。 <div class="min"> <button @click="change">点击我</button> <div v-show="show"> 显示隐藏的内容 </div>...

vue 在nginx下页面刷新出现404问题解决和在nginx下页面加载了js但是页面显示空白问题解决

一、vue 在nginx下页面刷新出现404   在网上翻遍了所有这样问题的解决办法,全都是一个解决办法也是正确的解决办法,(后来在vue官网上关于history方式出现404解决方法也是这样说的),只是没有表达完整,可能会让比较急于解决这个问题的人简单复制却始终解决不了问题 nginx正确的配置: 1、如果是在根目录则配置如下 location / { ...