001.
public
boolean
dispatchTouchEvent(MotionEvent ev) {
002.
if
(mInputEventConsistencyVerifier !=
null
) {
003.
mInputEventConsistencyVerifier.onTouchEvent(ev,
1
);
004.
}
005.
006.
boolean
handled =
false
;
007.
if
(onFilterTouchEventForSecurity(ev)) {
008.
final
int
action = ev.getAction();
009.
final
int
actionMasked = action & MotionEvent.ACTION_MASK;
010.
011.
// Handle an initial down.
012.
if
(actionMasked == MotionEvent.ACTION_DOWN) {
013.
// Throw away all previous state when starting a new touch gesture.
014.
// The framework may have dropped the up or cancel event for the previous gesture
015.
// due to an app switch, ANR, or some other state change.
016.
cancelAndClearTouchTargets(ev);
017.
resetTouchState();
018.
}
019.
020.
// Check for interception.
021.
final
boolean
intercepted;
022.
if
(actionMasked == MotionEvent.ACTION_DOWN
023.
|| mFirstTouchTarget !=
null
) {
024.
final
boolean
disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) !=
0
;
025.
if
(!disallowIntercept) {
026.
<strong>intercepted = onInterceptTouchEvent(ev);</strong>
027.
ev.setAction(action);
// restore action in case it was changed
028.
}
else
{
029.
intercepted =
false
;
030.
}
031.
}
else
{
032.
// There are no touch targets and this action is not an initial down
033.
// so this view group continues to intercept touches.
034.
intercepted =
true
;
035.
}
036.
037.
// Check for cancelation.
038.
final
boolean
canceled = resetCancelNextUpFlag(
this
)
039.
|| actionMasked == MotionEvent.ACTION_CANCEL;
040.
041.
// Update list of touch targets for pointer down, if needed.
042.
final
boolean
split = (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) !=
0
;
043.
TouchTarget newTouchTarget =
null
;
044.
boolean
alreadyDispatchedToNewTouchTarget =
false
;
045.
<strong>
if
(!canceled && !intercepted)</strong> {
046.
if
(actionMasked == MotionEvent.ACTION_DOWN
047.
|| (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN)
048.
|| actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
049.
final
int
actionIndex = ev.getActionIndex();
// always 0 for down
050.
final
int
idBitsToAssign = split ?
1
<< ev.getPointerId(actionIndex)
051.
: TouchTarget.ALL_POINTER_IDS;
052.
053.
// Clean up earlier touch targets for this pointer id in case they
054.
// have become out of sync.
055.
removePointersFromTouchTargets(idBitsToAssign);
056.
057.
final
int
childrenCount = mChildrenCount;
058.
if
(childrenCount !=
0
) {
059.
// Find a child that can receive the event.
060.
// Scan children from front to back.
061.
final
View[] children = mChildren;
062.
final
float
x = ev.getX(actionIndex);
063.
final
float
y = ev.getY(actionIndex);
064.
065.
final
boolean
customOrder = isChildrenDrawingOrderEnabled();
066.
for
(
int
i = childrenCount -
1
; i >=
0
; i--) {
067.
final
int
childIndex = customOrder ?
068.
getChildDrawingOrder(childrenCount, i) : i;
069.
final
View child = children[childIndex];
070.
if
(!canViewReceivePointerEvents(child)
071.
|| !isTransformedTouchPointInView(x, y, child,
null
)) {
072.
continue
;
073.
}
074.
075.
newTouchTarget = getTouchTarget(child);
076.
if
(newTouchTarget !=
null
) {
077.
// Child is already receiving touch within its bounds.
078.
// Give it the new pointer in addition to the ones it is handling.
079.
newTouchTarget.pointerIdBits |= idBitsToAssign;
080.
break
;
081.
}
082.
083.
resetCancelNextUpFlag(child);
084.
if
(dispatchTransformedTouchEvent(ev,
false
, child, idBitsToAssign)) {
085.
// Child wants to receive touch within its bounds.
086.
mLastTouchDownTime = ev.getDownTime();
087.
mLastTouchDownIndex = childIndex;
088.
mLastTouchDownX = ev.getX();
089.
mLastTouchDownY = ev.getY();
090.
newTouchTarget = addTouchTarget(child, idBitsToAssign);
091.
alreadyDispatchedToNewTouchTarget =
true
;
092.
break
;
093.
}
094.
}
095.
}
096.
097.
if
(newTouchTarget ==
null
&& mFirstTouchTarget !=
null
) {
098.
// Did not find a child to receive the event.
099.
// Assign the pointer to the least recently added target.
100.
newTouchTarget = mFirstTouchTarget;
101.
while
(newTouchTarget.next !=
null
) {
102.
newTouchTarget = newTouchTarget.next;
103.
}
104.
newTouchTarget.pointerIdBits |= idBitsToAssign;
105.
}
106.
}
107.
}
108.
109.
// Dispatch to touch targets.
110.
if
(mFirstTouchTarget ==
null
) {
111.
// No touch targets so treat this as an ordinary view.
112.
handled = dispatchTransformedTouchEvent(ev, canceled,
null
,
113.
TouchTarget.ALL_POINTER_IDS);
114.
}
else
{
115.
// Dispatch to touch targets, excluding the new touch target if we already
116.
// dispatched to it. Cancel touch targets if necessary.
117.
TouchTarget predecessor =
null
;
118.
TouchTarget target = mFirstTouchTarget;
119.
while
(target !=
null
) {
120.
final
TouchTarget next = target.next;
121.
if
(alreadyDispatchedToNewTouchTarget && target == newTouchTarget) {
122.
handled =
true
;
123.
}
else
{
124.
final
boolean
cancelChild = resetCancelNextUpFlag(target.child)
125.
|| intercepted;
126.
if
(dispatchTransformedTouchEvent(ev, cancelChild,
127.
target.child, target.pointerIdBits)) {
128.
handled =
true
;
129.
}
130.
if
(cancelChild) {
131.
if
(predecessor ==
null
) {
132.
mFirstTouchTarget = next;
133.
}
else
{
134.
predecessor.next = next;
135.
}
136.
target.recycle();
137.
target = next;
138.
continue
;
139.
}
140.
}
141.
predecessor = target;
142.
target = next;
143.
}
144.
}
145.
146.
// Update list of touch targets for pointer up or cancel, if needed.
147.
if
(canceled
148.
|| actionMasked == MotionEvent.ACTION_UP
149.
|| actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
150.
resetTouchState();
151.
}
else
if
(split && actionMasked == MotionEvent.ACTION_POINTER_UP) {
152.
final
int
actionIndex = ev.getActionIndex();
153.
final
int
idBitsToRemove =
1
<< ev.getPointerId(actionIndex);
154.
removePointersFromTouchTargets(idBitsToRemove);
155.
}
156.
}
157.
158.
if
(!handled && mInputEventConsistencyVerifier !=
null
) {
159.
mInputEventConsistencyVerifier.onUnhandledEvent(ev,
1
);
160.
}
161.
return
handled;
162.
}
联系客服