开发React Native 应用笔记

1.onResponderMove有时候返回值不对的问题

在做进度条的时候,处理onResponderMove的事件的时候,有时候发现进度条在拖动的时候跳动,最后发现原因是onResponderMove返回的event值有些问题。

这是布局

<View style={[styles.container , this.props.style]}
                 pointerEvents = "box-only"
                 onStartShouldSetResponder = {()=>{return true}}
                 onMoveShouldSetResponder = {()=>{return true}}
                 onResponderStart = {this._onResponderStart.bind(this)}
                 onResponderMove = {this._onResponderMove.bind(this)}
                 onResponderRelease = {this._onResponderRelease.bind(this)}
                 onLayout = {this._onLayout.bind(this)}>

               <View style = {[ styles.progressBackground, { height:progressHeight }]}/>
               <View style = {[styles.secondProgress, { marginTop : -progressHeight, height:progressHeight , width:this.state.secondProgress}]}/>
               <View style = {[ styles.firstProgress, {  marginTop : -progressHeight,height:progressHeight , width:firstProgressWidth}]}/>
               <View style = {[styles.slider , {position:"absolute" , left:firstProgressWidth}]}/>

最后发现是因为view堆叠在一块,触摸的时候事件返回的位置信息有点问题。最好处理就是事件只让最外面View处理就行路。

最后查看资料有一个叫pointerEvent的属性,是用来处理堆叠在一起的View事件的属性。看路文档之后最后选择“box-only”完美解决

pointerEvent官方介绍
pointerEvent参考

2.onResponderMove的参数event.nativeEvent.locationX不会更新的问题

这是React Native的一个bug,正在Android中出现,IOS没有问题
参见issue

在最新的版本中已经修复了,但是在低版本中有问题
还好event.nativeEvent.pageX这个值更新了,就用这个值来解决问题就行了
解决办法如下:

var x = event.nativeEvent.locationX;
        if (Platform.OS === "android"){
            x = event.nativeEvent.pageX - this.layout.x
        }

在0.44.3中是有问题的,最新版本修复此bug

3.Component的生命周期控制

我本人是做原生开发的,遇到这个问题是做视频全屏切换需求的时候,要是原生开发其实就很简单了,直接将VideoView放到Activity的根View当中就可以了,这样切换的时候,VideoView不会被销毁在重新创建。天真的我在ReactNative当中也想这也搞,最后发现你根本控制不了Component的生命周期。

假设VideoComponent对应的原生的VideoViewMananger。那么在VideoComponent挂载的时候会调用VideoViewManager的createNewInstance来创建新的实例。在卸载的时候也会调用onDropViewInstance。

所以在RN当中,View组件的节点与节点之间的层级一般是不能改变的。并不能简单的像在原生开发当中,将一个View移除,在添加到另一个ViewGroup当中。

4.React Native 没有遵守Android的View的测量,布局,绘制,这个流程

在RN自定义View组件的时候,在自定义的View组件中掉用requestLayout不会引发重新布局的。
原因:在ReactRootView当中的onLayout没事实现

  @Override
  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    // No-op since UIManagerModule handles actually laying out children.
  }

所以布局到ReactRootView就停止了,不会继续传递下去。

这会有什么问题呢?会让你在自定义一些复杂组件的时候,内部的View如果需要重新布局,可能就很麻烦。

假如,我们要做一个VideoView的组件,VideoView可能是一个RelativeLayout,里面放一个SurfaceView。一般在mediaPlayer回调视频宽高的方法的时候需要对SurfaceView重新计算大小和布局,这是就要发送一个requestLayout请求。

在RN下一般没反应的,肯定不会重新布局。而RN的源码中给了一个临时方案

  private final Runnable measureAndLayout = new Runnable() {
    @Override
    public void run() {
      measure(
          MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
          MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
      layout(getLeft(), getTop(), getRight(), getBottom());
    }
  };

  @Override
  public void requestLayout() {
    super.requestLayout();

    // The spinner relies on a measure + layout pass happening after it calls requestLayout().
    // Without this, the widget never actually changes the selection and doesn't call the
    // appropriate listeners. Since we override onLayout in our ViewGroups, a layout pass never
    // happens after a call to requestLayout, so we simulate one here.
    post(measureAndLayout);
  }

这段代码是在ReactPicker这个类当中复制过来的。

5. React Native 的View 的设计

6.在View组件中onDraw函数

在自定义组件中调用invalidate()会引发视图重绘,RN的绘制也有很大问题。

7. Modal这个类在Android上最好不要用

Modal根本没有考虑上面有对话框的问题,如果Modal覆盖有对话框,从后台切换到前台,Modal会覆盖对话框。
而且Modal的在前后胎切换的时候体验很不好,会重复创建。

8.react native send command to a non-existing view

在JS对接Android原生View的时候出现的。

JS:
            <View>
                <TALVideoView
                    dataSource = {this.props.dataSource}
                    onPreparedEvent = {()=>this.start()}
                    { ... this.props}
                />
            </View>

Java:
    @Nullable
    @Override
    public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
        Map<String, Object> map = new HashMap<>();
        map.put("WL_onPreparedEvent" , MapBuilder.of("registrationName", "onPreparedEvent"));
        return map;
    }

由于事件不会冒泡传,所以只看最外层的View没有onPreparedEvent就报错了。

方案:去掉最外的View或者用getExportedCustomBubblingEventTypeConstants

9. RN和Kotlin写的模块对接的时候编译的bug

用Kotlin写的模块,对接RN的时候,模块的名字正确没有重复,但是在JS端总是获取不到对象。

const module = NativeModules.xxxxx; //总是返回null

可能是Kotlin编译的问题,clean一下项目在运行就可以了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容