react-native源码分析系列四 ReactRootView

本文深入分析了ReactNative中ReactRootView如何处理触摸事件,包括touch的分发、目标视图的查找以及事件传递到JS层的过程。重点探讨了ReactRootView的onInterceptTouchEvent、onTouchEvent以及handleTouchEvent方法,以及EventDispatcher在事件调度中的作用,揭示了RN中触控事件从Native到JS的传递机制。
摘要由CSDN通过智能技术生成
前面系列文章分析了react-native js代码和java jni代码的交互通道。
react-native第二个重要的部分自然是它对view的处理,如何使用js代码绘制出"native"控件是我们接下来系列文章的主要内容。
在第一篇文章的时候我们看到过一个ReactRootView 一个负责touch分发的根view。因此,这篇文章先看下这个view的实现。


ReactRootView.java
public class ReactRootView extends SizeMonitoringFrameLayout implementsRootView
      /*****
RootView.java
public interfaceRootView {
/**
   * Called when a child starts a native gesture (e.g. a scroll in a ScrollView). Should be called
   * from the child's onTouchIntercepted implementation.
   */
  void onChildStartedNativeGesture(MotionEvent androidEvent);
}
     ******///

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
  handleTouchEvent(ev);
  return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
  handleTouchEvent(ev);
  super.onTouchEvent(ev);
  // In case when there is no children interested in handling touch event, we return true from
  // the root view in order to receive subsequent events related to that gesture
  return true;
}

@Override
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
  // No-op - override in order to still receive events to onInterceptTouchEvent
  // even when some other view disallow that
 //不调用super.requ..ent 是为了确保调用到onInterceptTouchEvent函数
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
// No-op sinceUIManagerModule handles actually laying out children.   //后面文章有分析这个manager
}                       

/**
* Main catalyst view is responsible for collecting and sending touch events to JS. This method
*reacts for an incoming android native touch events ({ @link MotionEvent}) andcalls into
* { @link com.facebook.react.uimanager.events.EventDispatcher} when appropriate.
* It uses { @link com.facebook.react.uimanager.TouchTargetManagerHelper#findTouchTargetView}
* helper method forfiguring out a react view ID in the case of ACTION_DOWN
* event (when the gesture starts).
*/                                                   
private void handleTouchEvent(MotionEvent ev) {                            //touch处理
           //介绍一下rn view的思路。观察一下rn官方的例子,你会发现在xml文件中一般只有reactRootView这一个viewgroup

         //因此rn在处理touch的时候要先找到target 然后使用dispather组件将touch转发给js封装好的控件

  if (mReactInstanceManager == null || !mIsAttachedToInstance ||
     mReactInstanceManager.getCurrentReactContext() == null) {
   return;
  }
  int action = ev.getAction() & MotionEvent.ACTION_MASK;
  ReactContext reactContext = mReactInstanceManager.getCurrentReactContext();
 EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class)
     .getEventDispatcher();                          //下面有分析具体实现
  if (action == MotionEvent.ACTION_DOWN) {
   mChildIsHandlingNativeGesture = false;
   mTargetTag = TouchTargetHelper.findTargetTagForTouch(ev.getRawY(), ev.getRawX(), this);  
                                                                                   //找到touch的目标(拿到一个view的id)(及其 对应的js实现的控件
  eventDispatcher.dispatchEvent(new TouchEvent(mTargetTag, TouchEventType.START, ev));
               //注意touchEvent封装了view的id ReactTouch的type 及touch实体(后面有分析-->用来传输给js控件
  } else if (mChildIsHandlingNativeGesture) {             
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值