IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android View的事件分流源码,android开发计算器源码 -> 正文阅读

[移动开发]Android View的事件分流源码,android开发计算器源码

作者:recommend-item-box type_blog clearfix

result = true;

}

// 重点 判断listenerInfo 中是否有事件listenter 并且mOnTouchListener.onTouc 返回true

ListenerInfo li = mListenerInfo;

if (li != null && li.mOnTouchListener != null

&& (mViewFlags & ENABLED_MASK) == ENABLED

&& li.mOnTouchListener.onTouch(this, event)) {

result = true;

}

// 第二个重点,如果上述判断为false,并且 onTouchEventr返回为true,消耗事件

if (!result && onTouchEvent(event)) {

result = true;

}

}

if (!result && mInputEventConsistencyVerifier != null) {

mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);

}

// Clean up after nested scrolls if this is the end of a gesture;

// also cancel it if we tried an ACTION_DOWN but we didn’t want the rest

// of the gesture.

if (actionMasked == MotionEvent.ACTION_UP ||

actionMasked == MotionEvent.ACTION_CANCEL ||

(actionMasked == MotionEvent.ACTION_DOWN && !result)) {

stopNestedScroll();

}

return result;

}

  1. dispatchTouchEvent中final int actionMasked = event.getActionMasked();

  2. ListenerInfo :将view所有的listener信息封装到一个对象中。

  3. 在该方法中有两个判断:

ListenerInfo li = mListenerInfo;

if (li != null && li.mOnTouchListener != null

&& (mViewFlags & ENABLED_MASK) == ENABLED

&& li.mOnTouchListener.onTouch(this, event)) {

result = true;

}

if (!result && onTouchEvent(event)) {

result = true;

}

复制代码

如果onTouchEvent或者是onTouchListenner是true的话,会消费此事件,同时,在这里也走了onTouchEvent

  • boolean onTouchEvent

  • MotionEvent.ACTION_UP:调用了PerformClick()

三个问题:

==============================================================

1. 在activity中调用了

==========================================================================

mTouchView.setOnTouchListener(new View.OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

Log.e(“TAG”, "onTouch: " + event.getAction());

return false;

}

});

mTouchView.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Log.e(“TAG”, "onClick: " );

}

});

/TabLayout*/

@Override

public boolean onTouchEvent(MotionEvent event) {

Log.e(“TAG”, "onTouchEvent: "+event.getAction());

return super.onTouchEvent(event);

}

复制代码

执行顺序:

2. 如果是Tablyout中直接return ture呢?

========================================================================================

不执行onClick,因为onClick在View.OntouchEvent中的ACTION_UP中,若直接return true 就不会走super中的方法。

3. 如果是dispatchEvent return true呢?

===========================================================================================

什么都不执行

分发流程

=============================================================

super.dispatchEvent->ListenerInfo->super.onTouchEvent(event)->ACTION_UP->performListener().

复制代码

2. ViewGroup的事件分发:

============================================================================

首先是actionDown:

if (actionMasked == MotionEvent.ACTION_DOWN

|| mFirstTouchTarget != null) { //

final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;

if (!disallowIntercept) {

intercepted = onInterceptTouchEvent(ev);

ev.setAction(action); // restore action in case it was changed

} else {

intercepted = false;

}

}

复制代码

  • mFirstTouchTarget: 这个很重要,只有在第一次按下的时候才会调用disallowIntercept,如果之后想要改变效果的时候,这是一个坑。

|—ViewGroup

| |—dispatchTouchEvent

| | |—onInterceptTouchEvent(ev)


有View会消耗时间的情况(比如点击,onTouchListener)

  • 第一次按下进来(down)—>ViewGroup.dispatchTouchEvent—>ViewGroup.onInterceptTouchEvent(ev)–>view.dispatchEvent—(view的那一套)

  • 第二次进来(move)ViewGroup.dispatchTouchEvent—>ViewGroup.onInterceptTouchEvent(ev)–>view.dispatchEvent—(view的那一套)

  • 第三次(up)ViewGroup.dispatchTouchEvent—>ViewGroup.onInterceptTouchEvent(ev)–>view.dispatchEvent—(view的那一套)–>view.onClick


子****View中没有消费事件的情况。只走一遍

  • 第一次进来(down)ViewGroup.dispatchTouchEvent—>ViewGroup.onInterceptTouchEvent(ev)–>view.dispatchEvent—view.onTouch–>onTouch Event

viewGroup的源码分析

=======================================================================

actionDown

/**

  • Clears all touch targets.

*/

private void clearTouchTargets() {

TouchTarget target = mFirstTouchTarget;

if (target != null) {

do {

TouchTarget next = target.next;

target.recycle();

target = next;

} while (target != null);

mFirstTouchTarget = null; //清除target

}

}

if (!canceled && !intercepted) // intercepted 默认是没有拦截

{

if (newTouchTarget == null && childrenCount != 0) {

for

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

(int i = childrenCount - 1; i >= 0; i–) {//反序列的for循环 先拿最上面的layout

if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {

}

}

}

}


/**

  • Transforms a motion event into the coordinate space of a particular child view,

  • filters out irrelevant pointer ids, and overrides its action if necessary.

  • If child is null, assumes the MotionEvent will be sent to this ViewGroup instead.

*/

private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,

View child, int desiredPointerIdBits) {

final boolean handled;

final int oldAction = event.getAction();

if (cancel || oldAction == MotionEvent.ACTION_CANCEL) {

event.setAction(MotionEvent.ACTION_CANCEL);

if (child == null) {

handled = super.dispatchTouchEvent(event);

} else {

handled = child.dispatchTouchEvent(event);

}

event.setAction(oldAction);

return handled;

}

// Calculate the number of pointers to deliver.

final int oldPointerIdBits = event.getPointerIdBits();

final int newPointerIdBits = oldPointerIdBits & desiredPointerIdBits;

// If for some reason we ended up in an inconsistent state where it looks like we

// might produce a motion event with no pointers in it, then drop the event.

if (newPointerIdBits == 0) {

return false;

}

final MotionEvent transformedEvent;

if (newPointerIdBits == oldPointerIdBits) {

if (child == null || child.hasIdentityMatrix()) {

if (child == null) {

handled = super.dispatchTouchEvent(event);

} else {

final float offsetX = mScrollX - child.mLeft;

final float offsetY = mScrollY - child.mTop;

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-11-26 08:57:51  更:2021-11-26 08:58:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:01:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码