Date post: | 15-Aug-2015 |
Category: |
Technology |
Upload: | droidcontlv |
View: | 87 times |
Download: | 1 times |
Journey of an eventThe Android touch
Marco Cova
Year in Review Riff
User eXperience
What is it?
• InputEvent extended by
• Mouse, pen, finger, trackball.
MotionEventKeyEvent
What is it?
• ACTION_DOWN
• ACTION_MOVE
• ACTION_UP - ACTION_CANCEL
Journey of a touch event
Journey of a touch eventActivity
ViewGroup
ViewGroup (DecorView)
View2View1
Activity
ViewGroup
View2
View1
Journey of a touch eventActivity
ViewGroup
ViewGroup (DecorView)
View2View1
Activity
ViewGroup
View2
View1
Journey of a touch eventActivity
ViewGroup
View2
View1
Activity
ViewGroup
ViewGroup (DecorView)
View2View1
Activity
ViewGroup
View2
View1
ViewActivity
ViewGroup
ViewGroup (DecorView)
View2View1
public boolean dispatchTouchEvent(MotionEvent event) { ...
if (..mOnTouchListener.onTouch(this, event)) { result = true; }
if (!result && onTouchEvent(event)) { result = true; } ... return result;}
View.java
public boolean onTouchEvent(MotionEvent event)
• OnClickListener
• OnLongClickListener
View
public boolean onTouchEvent(MotionEvent event) {
Activity
ViewGroup
View2
View1
ViewGroupActivity
ViewGroup (DecorView)
ViewGroup
View2View1
@Override public boolean dispatchTouchEvent(MotionEvent ev) { if (action == MotionEvent.ACTION_DOWN ...) { ArrayList<View> preorderedList = buildOrderedChildList(); for (int i = childrenCount -1; i >=0; i--) {
} } }
ViewGroup.java
. . .
if (!canViewReceivePointerEvents(child) || !isTransformedTouchPointInView(x, y, child, null)) { continue;}
. . .
ViewGroup.java
private boolean dispatchTransformedTouchEvent(…) { . . .
if (child == null) { handled = super.dispatchTouchEvent(transformedEvent); } else { handled = child.dispatchTouchEvent(transformedEvent); } . . .
return handled; }
ViewGroup.java
Activity
ViewGroup
View2
View1
Transformed EventActivity
ViewGroup
View2
View1
@Override public boolean dispatchTouchEvent(MotionEvent ev) { . . .
if (!disallowIntercept) { intercepted = onInterceptTouchEvent(ev); }
. . . }
ViewGroup.java
ViewGroup
• ACTION_CANCEL
• requestDisallowInterceptTouchEvent(boolean)
• State reset on ACTION_UP / CANCEL
What to do?!?
seekBar.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) {
if (event.getMaskAction() == MotionEvent.ACTION_DOWN) { v.getParent().requestDisallowInterceptTouchEvent(true); } return false; }});
Let’s recap
ViewGroup:
ViewGroup:
View1:
View1:
ViewGroup:
ViewGroup
View2
dispatchTouchEvent(..)
onInterceptTouchEvent(..)
dispatchTouchEvent(..)
onTouchEvent(..)
onTouchEvent(..)View1
Let’s recap
ViewGroup:
ViewGroup:
View1:
View1:
ViewGroup:
ViewGroup
View2View1
dispatchTouchEvent(..)
onInterceptTouchEvent(..)
dispatchTouchEvent(..)
onTouchEvent(..)
onTouchEvent(..)
Let’s recap
ViewGroup:
ViewGroup:
View1:
View1:
ViewGroup:
ViewGroup
View2View1
dispatchTouchEvent(..)
onInterceptTouchEvent(..)
dispatchTouchEvent(..)
onTouchEvent(..)
onTouchEvent(..)
Let’s recap
ViewGroup:
ViewGroup:
View1:
View1:
ViewGroup:
ViewGroup
View2View1
dispatchTouchEvent(..)
onInterceptTouchEvent(..)
dispatchTouchEvent(..)
onTouchEvent(..)
onTouchEvent(..)
Let’s recap
ViewGroup:
ViewGroup:
View1:
View1:
ViewGroup:
ViewGroup
View2View1
dispatchTouchEvent(..)
onInterceptTouchEvent(..)
dispatchTouchEvent(..)
onTouchEvent(..)
onTouchEvent(..)
Let’s recap
ACTION_DOWN
onTouchEvent - true
onTouchEvent - false
ViewGroup
View2View1
Let’s recap
ViewGroup onTouchEvent - true
ACTION_MOVE
View2View1
What’s at the top?Activity
ViewGroup
ViewGroup (DecorView)
View2View1
public boolean dispatchTouchEvent(MotionEvent ev) {
. . .
if (getWindow().superDispatchTouchEvent(ev)) { return true; }
return onTouchEvent(ev); }
Activity.java
Need help?
• GestureDetector: onScroll, onFling…
• ScaleGestureDetector: onScale
GestureDetectorpublic class MyView extends View { GestureDetector mGestureDetector; OnGestureListener mOnGestureListener; private void init() { mOnGestureListener = new SimpleOnGestureListener() { . . . }; mGestureDetector = new GestureDetector(getContext(), mOnGestureListener); }
@Override public boolean onTouchEvent(MotionEvent event) { boolean detectorHandled = mGestureDetector.onTouch(event); boolean superHandled = super.onTouchEvent(event); return detectorHandled || superHandled; } }
ViewConfiguration.java
• getScaleTouchSlop()
• getScaled…FlingVelocity()
• getLongPressTimeout()
Choreographer.java
void doFrame(long frameTimeNanos, int frame) { . . . doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos); doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos); doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos); . . . }
Multi-Touch
• ACTION_POINTER_DOWN / _UP
• ViewGroup MotionEvent splitting on _DOWN
• getActionIndex(), getX(int), getY(int)
parent ViewGroup
bounds
TouchDelegate
delegateView
• Parent bounds
• Click only checks
Questions?
Disclaimer: The information contained in these slides has been prepared from the author and the employer has no responsibility.