b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

触摸屏虚拟键盘 Android Touch事件传递机制全面解析(从WMS到View树)(7)

电脑杂谈  发布时间:2018-02-19 12:20:49  来源:网络整理

boolean alreadyDispatchedToNewTouchTarget = false; // 假设没有被取消。而且没有被拦截,就分发该事件,注意仅仅有down事件才会走到这里去分发。对于move和up事件。则会跳过这里。直接从 mFirstTouchTarget链表中找到之前消耗down事件的目标View,直接将move和up事件非法给它,后面的代码中我们会分析到。

if (!canceled && !intercepted) { //仅仅有down事件会走到这里 if (actionMasked == MotionEvent.ACTION_DOWN || (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN) || actionMasked == MotionEvent.ACTION_HOVER_MOVE) { //Touch事件的index,对于单点触控。一直为0,这里不用深究 final int actionIndex = ev.getActionIndex(); // always 0 for down final int idBitsToAssign = split ? 1 << ev.getPointerId(actionIndex) : TouchTarget.ALL_POINTER_IDS; // Clean up earlier touch targets for this pointer id in case they // have become out of sync. removePointersFromTouchTargets(idBitsToAssign); //该ViewGroup中子View的个数 final int childrenCount = mChildrenCount; if (newTouchTarget == null && childrenCount != 0) { //当前事件发生的位置 final float x = ev.getX(actionIndex); final float y = ev.getY(actionIndex); //保存该ViewGroup中子View final View[] children = mChildren; final boolean customOrder = isChildrenDrawingOrderEnabled(); //遍历子View,找到能消费该down事件的子View,对于类型为ViewGroup的子View,在分发的时候。会递归调用到它的dispatchTouchEvent方法继续进行分发。 for (int i = childrenCount - 1; i >= 0; i--) { final int childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i; final View child = children[childIndex]; //假设当前子View能够消费该down事件。而且该down事件发生的位置在当前子View的范围内,则继续运行。将down事件分发给它,否则,continue推断下一个子View可否接受该down事件。 if (!canViewReceivePointerEvents(child) || !isTransformedTouchPointInView(x, y, child, null)) { continue; } //推断该能接受该down事件的child是否已经在mFirstTouchTarget链表中。假设在的话,说明child已经消费掉了该down事件,直接跳出循环。我在写demo跟代码时,没有一次走到这里的,临时不是非常清楚,如何的场景下,代码会运行到这里的break。 newTouchTarget = getTouchTarget(child); if (newTouchTarget != null) { newTouchTarget.pointerIdBits |= idBitsToAssign; break; } resetCancelNextUpFlag(child); //假设该child还没有消费掉该down事件,就直接调用dispatchTransformedTouchEvent方法将该down事件传递给该child,该方法里面会调用到child的dispatchTouchEvent方法,假设该方法返回true,则说明child消费掉了该down事件,那么就运行if语句里的逻辑,将child添加到mFirstTouchTarget链表的表头,而且将该表头赋值给newTouchTarget(参见addTouchTarget方法),同一时候 alreadyDispatchedToNewTouchTarget置为true。说明有子view消费掉了该down事件。 if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) { // Child wants to receive touch within its bounds. mLastTouchDownTime = ev.getDownTime(); mLastTouchDownIndex = childIndex; mLastTouchDownX = ev.getX(); mLastTouchDownY = ev.getY(); newTouchTarget = addTouchTarget(child, idBitsToAssign); alreadyDispatchedToNewTouchTarget = true; break; } } } //假设newTouchTarget为null。而且 mFirstTouchTarget不为null,也即没找到子View来消耗该事件,可是保存Touch事件的链表不为空,则把newTouchTarget赋值为最早加进(Least Recently added)mFirstTouchTarget链表的target。临时没全然搞明确这里的详细意思,跟代码都没有走到这里。 if (newTouchTarget == null && mFirstTouchTarget != null) { // Did not find a child to receive the event. // Assign the pointer to the least recently added target. newTouchTarget = mFirstTouchTarget; while (newTouchTarget.next != null) { newTouchTarget = newTouchTarget.next; } newTouchTarget.pointerIdBits |= idBitsToAssign; } } } //后面在处理MOVE和UP事件时。会直接依据上次的DOWN是否被消费掉来直接进行相应的处理。


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shouji/article-84984-7.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...