• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > React-Native系列Android——Touch事件原理及状态效果

React-Native系列Android——Touch事件原理及状态效果

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了突发事件就是紧急状态,无状态斗鱼直播事件,雅典 紧急状态事件,无状态事件,事件状态等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

React-Native系列Android——Touch事件原理及状态效果


Native原生相比于Hybrid或H5最大优点是具有流畅和复杂的交互效果,触摸事件便是其中重要一项,包括点击(Click)、长按(LongClick)、手势(gesture)等。

以最简单常见的点击(Click)为例,Native组件可以自定义selector,使得被点击的组件具有动态效果,Android 5.0以上甚至可以有涟漪效果(Material Design)。而这些在Hybrid或H5中很难实现,很多时候区分它们与原生最简单的方法就是检验点击交互效果。

React-Native的强大之处在于实现了较为全面的Touch事件机制,虽然仍略有缺陷,但相比于Hybrid或H5的体验而言,已经足足提高了一大截,下面分析讲解一下其实现原理,和具体使用方式。


1、Touch事件机制

如果阅读过React-Native源码的话,应该了解React-Native页面的UI根视图是ReactRootView,包路径是:com.facebook.react.ReactRootView,它是FramLayout的一个子类。

首先,来看一下ReactActivity这个页面基类,ReactRootView是如何作为React-Native的根视图被初始化及添加的。

public abstract class ReactActivity extends Activity implements DefaultHardwareBackBtnHandler {

...

  protected ReactRootView createRootView() {
    return new ReactRootView(this);
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (getUseDeveloperSupport() && Build.VERSION.SDK_INT >= 23) {
      // Get permission to show redbox in dev builds.
      if (!Settings.canDrawOverlays(this)) {
        Intent serviceIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
        startActivity(serviceIntent);
        FLog.w(ReactConstants.TAG, REDBOX_PERMISSION_MESSAGE);
        Toast.makeText(this, REDBOX_PERMISSION_MESSAGE, Toast.LENGTH_LONG).show();
      }
    }

    mReactInstanceManager = createReactInstanceManager();
    ReactRootView mReactRootView = createRootView();
    mReactRootView.startReactApplication(mReactInstanceManager, getMainComponentName(), getLaunchOptions());
    setContentView(mReactRootView);
  }

...

}

在ReactActivity的onCreate这个生命周期里,直接实列化,然后作为当前Window的ContentView,也就可以认为其是所有React-Native组件的根视图。

熟悉Android触摸事件机制的,应该知道视图树中,触摸事件是逐级传递的,每个视图(View)中有两个接收和处理Touch事件的方法,分别是onInterceptTouchEvent和onTouchEvent,这两个方法的区别为:

onInterceptTouchEvent的传递层级是由父视图向子视图,顾名思义,通常用作事件拦截。
onTouchEvent的传递层级是由子视图向父视图,通常用作事件处理。

我们来看一下ReactRootView的事件接收和处理。

public class ReactRootView extends SizeMonitoringFrameLayout implements RootView {
   ...

     @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;
  }

   ...
}

很明显,这里onInterceptTouchEvent和onTouchEvent的处理都是全部交给handleTouchEvent方法统一处理的。

我们再继续看一下handleTouchEvent方法。

public class ReactRootView extends SizeMonitoringFrameLayout implements RootView {
   ...

    /**
   * 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}) and calls into
   * {@link com.facebook.react.uimanager.events.EventDispatcher} when appropriate.
   * It uses {@link com.facebook.react.uimanager.TouchTargetManagerHelper#findTouchTargetView}
   * helper method for figuring out a react view ID in the case of ACTION_DOWN
   * event (when the gesture starts).
   */
  private void handleTouchEvent(MotionEvent ev) {

   ...

   int action = ev.getAction() & MotionEvent.ACTION_MASK;
    ReactContext reactContext = mReactInstanceManager.getCurrentReactContext();
    EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class)
        .getEventDispatcher();
    if (action == MotionEvent.ACTION_DOWN) {

    ...

    mTargetTag = TouchTargetHelper.findTargetTagAndCoordinatesForTouch(
          ev.getX(),
          ev.getY(),
          this,
          mTargetCoordinates);    

    eventDispatcher.dispatchEvent(
          TouchEvent.obtain(
              mTargetTag,
              SystemClock.uptimeMillis(),
              TouchEventType.START,
              ev,
              mTargetCoordinates[0],
              mTargetCoordinates[1]));
    } else if (action == MotionEvent.ACTION_UP) {
      // End of the gesture. We reset target tag to -1 and expect no further event associated with
      // this gesture.
      eventDispatcher.dispatchEvent(
          TouchEvent.obtain(
              mTargetTag,
              SystemClock.uptimeMillis(),
              TouchEventType.END,
              ev,
              mTargetCoordinates[0],
              mTargetCoordinates[1]));
      mTargetTag = -1;
    } else if (action == MotionEvent.ACTION_MOVE) {
      // Update pointer position for current gesture
      eventDispatcher.dispatchEvent(
          TouchEvent.obtain(
              mTargetTag,
              SystemClock.uptimeMillis(),
              TouchEventType.MOVE,
              ev,
              mTargetCoordinates[0],
              mTargetCoordinates[1]));
    } else if (action == MotionEvent.ACTION_POINTER_DOWN) {
      // New pointer goes down, this can only happen after ACTION_DOWN is sent for the first pointer
      eventDispatcher.dispatchEvent(
          TouchEvent.obtain(
              mTargetTag,
              SystemClock.uptimeMillis(),
              TouchEventType.START,
              ev,
              mTargetCoordinates[0],
              mTargetCoordinates[1]));
    } else if (action == MotionEvent.ACTION_POINTER_UP) {
      // Exactly onw of the pointers goes up
      eventDispatcher.dispatchEvent(
          TouchEvent.obtain(
              mTargetTag,
              SystemClock.uptimeMillis(),
              TouchEventType.END,
              ev,
              mTargetCoordinates[0],
              mTargetCoordinates[1]));
    } else if (action == MotionEvent.ACTION_CANCEL) {
      dispatchCancelEvent(ev);
      mTargetTag = -1;
    }
  }
   ...
}

代码不是很多,也很好理解。先来看一下注释,意思是ReactRootView 负责收集和发送事件给JS,当原生触摸事件响应时通过EventDispatcher类发送,并且在Down事件时通过TouchTargetManagerHelper查找具体被触摸的子View。这里一语道破了触摸事件的核心原理:

所有React组件的触摸事件都是由ReactRootView统一处理,将具体被触摸组件和具体触摸事件发送给Javascript。其中隐藏的一层意思是:React组件自身不用处理触摸事件。

这个很关键,而具体被处理的触摸事件有以下6种,分别是ACTION_DOWN、ACTION_UP、ACTION_MOVE、ACTION_POINTER_DOWN、ACTION_POINTER_UP、ACTION_CANCEL,已经包含了几乎所有的手势动作。


2、Touch

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • React-Native系列Android——Touch事件原理及状态效果

相关文章

  • 2017-05-26Android V7包学习笔记更新中.....
  • 2017-05-26App内切换语言,app切换语言
  • 2017-05-26总结一下Android中主题(Theme)的正确玩法,androidtheme
  • 2017-05-26应该在find命令中使用-execdir代替-exec
  • 2017-05-26Android Studio发布应用
  • 2017-05-26Android Studio发布到Jcenter
  • 2017-05-26输入法出现时,局部上移的代码,输入法上移
  • 2017-05-26Android 四大组件之Activity(续2),androidactivity
  • 2017-05-26Android开发艺术探索学习笔记(三),android艺术探索
  • 2017-05-26【原】tinker dex文件格式的dump工具tinker-dex-dump,dextinker-dex-dump

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • redis配置文件参数解释说明
    • Andorid Scrolling Activity(CoordinatorLayout详情),scrollingactivity
    • Android 6.0 运行时权限处理完全解析,android6.0
    • Android--BroadcastReceiver应用详解
    • Android 5.0 Settings源码简要分析
    • Android端 配置极光推送
    • 银联支付,支付
    • andriod 获得应用程序名称,andriod应用程序
    • Android EventBus.getDefault()开源框架,eventbusgetdefault
    • Android中如何修改编译的资源ID值(默认值是0x7F...可以随意改成0x02~0x7E)

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有