zoukankan      html  css  js  c++  java
  • React-Native采坑总结

    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图片,也许有帮助,现在我们业务线都是使用这种方式,效果比较好。

  • 相关阅读:
    索引
    互联网技术中的算法摘要
    Struts2(六)
    Struts2(五)
    Struts2(四)
    Struts2(三)
    Struts2(二)
    Struts2(一)
    WebService(三)
    WebService(二)
  • 原文地址:https://www.cnblogs.com/star91/p/ReactNative-cai-keng-zong-jie.html
Copyright © 2011-2022 走看看