Example usage for android.view View hasFocusable

List of usage examples for android.view View hasFocusable

Introduction

In this page you can find the example usage for android.view View hasFocusable.

Prototype

public boolean hasFocusable() 

Source Link

Document

Returns true if this view is focusable or if it contains a reachable View for which #hasFocusable() returns true .

Usage

From source file:com.rbware.github.androidcouchpotato.widget.GridLayoutManager.java

private void scrollToFocusViewInLayout(boolean hadFocus, boolean alignToView) {
    View focusView = findViewByPosition(mFocusPosition);
    if (focusView != null && alignToView) {
        scrollToView(focusView, false);//  w  w w .  j  a v  a  2s . co m
    }
    if (focusView != null && hadFocus && !focusView.hasFocus()) {
        focusView.requestFocus();
    } else if (!hadFocus && !mBaseGridView.hasFocus()) {
        if (focusView != null && focusView.hasFocusable()) {
            mBaseGridView.focusableViewAvailable(focusView);
        } else {
            for (int i = 0, count = getChildCount(); i < count; i++) {
                focusView = getChildAt(i);
                if (focusView != null && focusView.hasFocusable()) {
                    mBaseGridView.focusableViewAvailable(focusView);
                    break;
                }
            }
            // focusViewAvailable() might focus to the view, scroll to it if that is the case.
            if (alignToView && focusView != null && focusView.hasFocus()) {
                scrollToView(focusView, false);
            }
        }
    }
}

From source file:com.bulletnoid.android.widget.StaggeredGridView.StaggeredGridView2.java

private void onTouchUp(MotionEvent ev) {
    switch (mTouchMode) {
    case TOUCH_MODE_DOWN:
    case TOUCH_MODE_TAP:
    case TOUCH_MODE_DONE_WAITING:
        final int motionPosition = mMotionPosition;
        final View child = getChildAt(motionPosition - mFirstPosition);
        if (child != null) {
            if (mTouchMode != TOUCH_MODE_DOWN) {
                child.setPressed(false);
            }//from www.j av  a  2 s  . c  o m

            final float x = ev.getX();
            final boolean inList = x > getPaddingLeft()
                    /*mListPadding.left*/ && x < getWidth() - getPaddingRight()/*mListPadding.right*/;
            if (inList && !child.hasFocusable()) {
                if (mPerformClick == null) {
                    mPerformClick = new PerformClick();
                }

                final PerformClick performClick = mPerformClick;
                performClick.mClickMotionPosition = motionPosition;
                performClick.rememberWindowAttachCount();

                //mResurrectToPosition = motionPosition;
                Log.d(TAG, "up:" + mTouchMode + "");
                if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) {
                    removeCallbacks(
                            mTouchMode == TOUCH_MODE_DOWN ? mPendingCheckForTap : mPendingCheckForLongPress);
                    //mLayoutMode = LAYOUT_NORMAL;
                    if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
                        mTouchMode = TOUCH_MODE_TAP;
                        //setSelectedPositionInt(mMotionPosition);
                        layoutChildren(mDataChanged);
                        child.setPressed(true);
                        positionSelector(mMotionPosition, child);
                        setPressed(true);
                        if (mSelector != null) {
                            Drawable d = mSelector.getCurrent();
                            if (d != null && d instanceof TransitionDrawable) {
                                ((TransitionDrawable) d).resetTransition();
                            }
                        }
                        if (mTouchModeReset != null) {
                            removeCallbacks(mTouchModeReset);
                        }
                        mTouchModeReset = new Runnable() {
                            @Override
                            public void run() {
                                mTouchModeReset = null;
                                mTouchMode = TOUCH_MODE_REST;
                                child.setPressed(false);
                                setPressed(false);
                                if (!mDataChanged /*&& isAttachedToWindow()*/) {
                                    performClick.run();
                                }
                            }
                        };
                        postDelayed(mTouchModeReset, ViewConfiguration.getPressedStateDuration());
                    } else {
                        mTouchMode = TOUCH_MODE_REST;
                        updateSelectorState();
                    }
                    return;
                } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
                    performClick.run();
                }
            }
        }
        mTouchMode = TOUCH_MODE_REST;
        updateSelectorState();
        break;
    case TOUCH_MODE_DRAGGING:
        final int childCount = getChildCount();
        if (childCount > 0) {
            final int firstChildTop = getChildAt(0).getTop();
            final int lastChildBottom = getChildAt(childCount - 1).getBottom();
            final int contentTop = getPaddingTop();//mListPadding.top;
            final int contentBottom = getHeight() - getPaddingBottom();//mListPadding.bottom;
            if (mFirstPosition == 0 && firstChildTop >= contentTop && mFirstPosition + childCount < mItemCount
                    && lastChildBottom <= getHeight() - contentBottom) {
                mTouchMode = TOUCH_MODE_REST;
                reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
            } else {
                final VelocityTracker velocityTracker = mVelocityTracker;
                velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);

                final int initialVelocity = (int) (velocityTracker.getYVelocity(mActivePointerId)
                        * mVelocityScale);
                // Fling if we have enough velocity and we aren't at a boundary.
                // Since we can potentially overfling more than we can overscroll, don't
                // allow the weird behavior where you can scroll to a boundary then
                // fling further.
                if (Math.abs(initialVelocity) > mMinimumVelocity
                        && !((mFirstPosition == 0 && firstChildTop == contentTop - mOverscrollDistance)
                                || (mFirstPosition + childCount == mItemCount
                                        && lastChildBottom == contentBottom + mOverscrollDistance))) {
                    if (mFlingRunnable == null) {
                        mFlingRunnable = new FlingRunnable();
                    }
                    reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);

                    mFlingRunnable.start(-initialVelocity);
                } else {
                    mTouchMode = TOUCH_MODE_REST;
                    reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                    if (mFlingRunnable != null) {
                        mFlingRunnable.endFling();
                    }
                    /*if (mPositionScroller != null) {
                        mPositionScroller.stop();
                    }*/
                }
            }
        } else {
            mTouchMode = TOUCH_MODE_REST;
            reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
        }
        break;

    case TOUCH_MODE_OVERSCROLL:
        if (mFlingRunnable == null) {
            mFlingRunnable = new FlingRunnable();
        }
        final VelocityTracker velocityTracker = mVelocityTracker;
        velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
        final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);

        reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
        if (Math.abs(initialVelocity) > mMinimumVelocity) {
            mFlingRunnable.startOverfling(-initialVelocity);
        } else {
            mFlingRunnable.startSpringback();
        }

        break;
    }

    setPressed(false);

    /*if (mEdgeGlowTop != null) {
    mEdgeGlowTop.onRelease();
    mEdgeGlowBottom.onRelease();
    }*/

    // Need to redraw since we probably aren't drawing the selector anymore
    invalidate();
    removeCallbacks(mPendingCheckForLongPress);
    recycleVelocityTracker();

    mActivePointerId = INVALID_POINTER;

    /*if (PROFILE_SCROLLING) {
    if (mScrollProfilingStarted) {
        Debug.stopMethodTracing();
        mScrollProfilingStarted = false;
    }
    }
            
    if (mScrollStrictSpan != null) {
    mScrollStrictSpan.finish();
    mScrollStrictSpan = null;
    }*/
}

From source file:nz.ac.otago.psyanlab.common.designer.program.stage.StageView.java

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (!isEnabled()) {
        // Ignore touch events if not enabled.
        return false;
    }//from w w  w . j  a v  a2  s  .  c  o  m

    final int action = event.getAction();
    final int pointerCount = event.getPointerCount();
    final Handler handler = getHandler();

    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_POINTER_DOWN: {
        // Throw away event if we have already seen at least this many
        // fingers before.
        if (mMaxFingersDown > pointerCount) {
            return true;
        }

        if (handler != null) {
            handler.removeCallbacks(mPendingCheckForTap);
            handler.removeCallbacks(mPendingCheckForLongPress);
        }

        mPendingCheckForTap = new CheckForTap();
        postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());

        mMaxFingersDown = pointerCount;

        mMotionPosition = INVALID_POSITION;
        updateMotionCoords(event, pointerCount);

        mTouchMode = TOUCH_MODE_DOWN;

        return true;
    }

    case MotionEvent.ACTION_DOWN: {
        mMaxFingersDown = pointerCount;

        if (mPendingCheckForTap == null) {
            mPendingCheckForTap = new CheckForTap();
        }
        postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());

        updateMotionCoords(event, pointerCount);
        mMotionPosition = pointToPosition(mMotionX.get(0).intValue(), mMotionY.get(0).intValue());

        mTouchMode = TOUCH_MODE_DOWN;

        return true;
    }

    case MotionEvent.ACTION_MOVE: {
        if (mMaxFingersDown == 1 && mMotionPosition != NO_MATCHED_CHILD
                && mMotionPosition == pointToPosition((int) event.getX(), (int) event.getY())) {
            // Ignore movement in single touch mode until the user has
            // moved out of the prop hit area.
            return true;
        }

        boolean moveIsOverSlop = false;
        int touchSlop = mMaxFingersDown > 1 ? mTouchSlop * 6 : mTouchSlop;
        for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) {
            int pointerId = event.getPointerId(pointerIndex);
            moveIsOverSlop = moveIsOverSlop
                    || Math.abs(event.getY(pointerIndex) - mMotionY.get(pointerId)) > touchSlop
                    || Math.abs(event.getX(pointerIndex) - mMotionX.get(pointerId)) > touchSlop;
        }

        if (mTouchMode != TOUCH_MODE_AT_REST && moveIsOverSlop) {
            // Too much movement to be a tap event.
            mTouchMode = TOUCH_MODE_AT_REST;
            final View child = getChildAt(mMotionPosition);
            if (child != null) {
                child.setPressed(false);
            }
            setPressed(false);
            if (handler != null) {
                handler.removeCallbacks(mPendingCheckForLongPress);
            }
            mMotionPosition = NO_MATCHED_CHILD;
            updateSelectorState();
            invalidate();
        }
        return true;
    }

    case MotionEvent.ACTION_UP: {
        if (mTouchMode == TOUCH_MODE_FINISHED_LONG_PRESS) {
            return true;
        }

        if (mTouchMode == TOUCH_MODE_AT_REST) {
            break;
        }

        // Handle stage multi-touch.

        if (mMotionPosition == NO_MATCHED_CHILD) {
            if (mPerformPropClick == null) {
                mPerformPropClick = new PerformClick();
            }

            final PerformClick performPropClick = mPerformPropClick;
            performPropClick.mClickMotionPosition = mMotionPosition;
            performPropClick.rememberWindowAttachCount();

            if (mTouchMode != TOUCH_MODE_DOWN || mTouchMode != TOUCH_MODE_TAP) {
                if (handler != null) {
                    handler.removeCallbacks(
                            mTouchMode == TOUCH_MODE_DOWN ? mPendingCheckForTap : mPendingCheckForLongPress);
                }

                if (!mDataChanged) {
                    // Got here so must be a tap. The long press would
                    // have triggered inside the delayed runnable.
                    mTouchMode = TOUCH_MODE_TAP;
                    positionSelector(this);
                    setPressed(true);
                    updateSelectorState();
                    invalidate();

                    resetSelectorTransition(getVirtualFingers());

                    if (mTouchModeReset != null) {
                        removeCallbacks(mTouchModeReset);
                    }
                    mTouchModeReset = new Runnable() {
                        @Override
                        public void run() {
                            mTouchMode = TOUCH_MODE_AT_REST;
                            setPressed(false);
                            if (!mDataChanged) {
                                performPropClick.run();
                            }
                            updateSelectorState();
                            invalidate();
                        }
                    };
                    postDelayed(mTouchModeReset, ViewConfiguration.getPressedStateDuration());
                } else {
                    mTouchMode = TOUCH_MODE_AT_REST;
                }
            } else if (!mDataChanged) {
                performPropClick.run();
            }
        } else {
            // Handle touch on child.
            final View child = getChildAt(mMotionPosition);
            if (child != null && !child.hasFocusable()) {
                if (mTouchMode != TOUCH_MODE_DOWN) {
                    child.setPressed(false);
                }

                if (mPerformPropClick == null) {
                    mPerformPropClick = new PerformClick();
                }

                final PerformClick performPropClick = mPerformPropClick;
                performPropClick.mClickMotionPosition = mMotionPosition;
                performPropClick.rememberWindowAttachCount();

                if (mTouchMode != TOUCH_MODE_DOWN || mTouchMode != TOUCH_MODE_TAP) {
                    if (handler != null) {
                        handler.removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ? mPendingCheckForTap
                                : mPendingCheckForLongPress);
                    }

                    if (!mDataChanged) {
                        // Got here so must be a tap. The long press
                        // would
                        // have triggered inside the delayed runnable.
                        mTouchMode = TOUCH_MODE_TAP;
                        child.setPressed(true);
                        positionSelector(child);
                        setPressed(true);
                        updateSelectorState();
                        invalidate();

                        resetSelectorTransition(getVirtualFingers());

                        if (mTouchModeReset != null) {
                            removeCallbacks(mTouchModeReset);
                        }
                        mTouchModeReset = new Runnable() {
                            @Override
                            public void run() {
                                mTouchMode = TOUCH_MODE_AT_REST;
                                child.setPressed(false);
                                setPressed(false);
                                updateSelectorState();
                                invalidate();
                                if (!mDataChanged) {
                                    performPropClick.run();
                                }
                            }
                        };
                        postDelayed(mTouchModeReset, ViewConfiguration.getPressedStateDuration());
                    } else {
                        mTouchMode = TOUCH_MODE_AT_REST;
                        updateSelectorState();
                        invalidate();
                    }
                } else if (!mDataChanged) {
                    performPropClick.run();
                }
            }
        }
        return true;
    }
    }
    return true;
}

From source file:com.appunite.list.AbsHorizontalListView.java

/**
 * Sets the selector state to "pressed" and posts a CheckForKeyLongPress to see if
 * this is a long press.//from  w  w w  .j  a v a 2  s. c  o m
 */
void keyPressed() {
    if (!isEnabled() || !isClickable()) {
        return;
    }

    Drawable selector = mSelector;
    Rect selectorRect = mSelectorRect;
    if (selector != null && (isFocused() || touchModeDrawsInPressedState()) && !selectorRect.isEmpty()) {

        final View v = getChildAt(mSelectedPosition - mFirstPosition);

        if (v != null) {
            if (v.hasFocusable())
                return;
            v.setPressed(true);
        }
        setPressed(true);

        final boolean longClickable = isLongClickable();
        Drawable d = selector.getCurrent();
        if (d != null && d instanceof TransitionDrawable) {
            if (longClickable) {
                ((TransitionDrawable) d).startTransition(ViewConfiguration.getLongPressTimeout());
            } else {
                ((TransitionDrawable) d).resetTransition();
            }
        }
        if (longClickable && !mDataChanged) {
            if (mPendingCheckForKeyLongPress == null) {
                mPendingCheckForKeyLongPress = new CheckForKeyLongPress();
            }
            mPendingCheckForKeyLongPress.rememberWindowAttachCount();
            postDelayed(mPendingCheckForKeyLongPress, ViewConfiguration.getLongPressTimeout());
        }
    }
}

From source file:com.aliasapps.seq.scroller.TwoWayView.java

/**
 * Sets the selector state to "pressed" and posts a CheckForKeyLongPress to see if
 * this is a long press.//from   w w w.  ja  va  2  s  .c om
 */
private void keyPressed() {
    if (!isEnabled() || !isClickable()) {
        return;
    }

    final Drawable selector = mSelector;
    final Rect selectorRect = mSelectorRect;

    if (selector != null && (isFocused() || touchModeDrawsInPressedState()) && !selectorRect.isEmpty()) {

        final View child = getChildAt(mSelectedPosition - mFirstPosition);

        if (child != null) {
            if (child.hasFocusable()) {
                return;
            }

            child.setPressed(true);
        }

        setPressed(true);

        final boolean longClickable = isLongClickable();
        final Drawable d = selector.getCurrent();
        if (d != null && d instanceof TransitionDrawable) {
            if (longClickable) {
                ((TransitionDrawable) d).startTransition(ViewConfiguration.getLongPressTimeout());
            } else {
                ((TransitionDrawable) d).resetTransition();
            }
        }

        if (longClickable && !mDataChanged) {
            if (mPendingCheckForKeyLongPress == null) {
                mPendingCheckForKeyLongPress = new CheckForKeyLongPress();
            }

            mPendingCheckForKeyLongPress.rememberWindowAttachCount();
            postDelayed(mPendingCheckForKeyLongPress, ViewConfiguration.getLongPressTimeout());
        }
    }
}

From source file:com.example.libwidgettv.bak.AbsListView.java

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (!isEnabled()) {
        // A disabled view that is clickable still consumes the touch
        // events, it just doesn't respond to them.
        return isClickable() || isLongClickable();
    }/*from   w ww .  ja va 2 s  .c om*/

    if (mFastScroller != null) {
        boolean intercepted = mFastScroller.onTouchEvent(ev);
        if (intercepted) {
            return true;
        }
    }

    final int action = ev.getAction();

    View v;

    initVelocityTrackerIfNotExists();
    mVelocityTracker.addMovement(ev);

    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN: {
        switch (mTouchMode) {
        case TOUCH_MODE_OVERFLING: {
            mFlingRunnable.endFling();
            if (mPositionScroller != null) {
                mPositionScroller.stop();
            }
            mTouchMode = TOUCH_MODE_OVERSCROLL;
            mMotionX = (int) ev.getX();
            mMotionY = mLastY = (int) ev.getY();
            mMotionCorrection = 0;
            mActivePointerId = ev.getPointerId(0);
            mDirection = 0;
            break;
        }

        default: {
            mActivePointerId = ev.getPointerId(0);
            final int x = (int) ev.getX();
            final int y = (int) ev.getY();
            int motionPosition = pointToPosition(x, y);
            if (!mDataChanged) {
                if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0)
                        && (getAdapter().isEnabled(motionPosition))) {
                    // User clicked on an actual view (and was not stopping
                    // a fling).
                    // It might be a click or a scroll. Assume it is a click
                    // until
                    // proven otherwise
                    mTouchMode = TOUCH_MODE_DOWN;
                    // FIXME Debounce
                    if (mPendingCheckForTap == null) {
                        mPendingCheckForTap = new CheckForTap();
                    }
                    postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
                } else {
                    if (mTouchMode == TOUCH_MODE_FLING) {
                        // Stopped a fling. It is a scroll.
                        createScrollingCache();
                        mTouchMode = TOUCH_MODE_SCROLL;
                        mMotionCorrection = 0;
                        motionPosition = findMotionRow(y);
                        mFlingRunnable.flywheelTouch();
                    }
                }
            }

            if (motionPosition >= 0) {
                // Remember where the motion event started
                v = getChildAt(motionPosition - mFirstPosition);
                mMotionViewOriginalTop = v.getTop();
            }
            mMotionX = x;
            mMotionY = y;
            mMotionPosition = motionPosition;
            mLastY = Integer.MIN_VALUE;
            break;
        }
        }

        // if (performButtonActionOnTouchDown(ev)) {
        // if (mTouchMode == TOUCH_MODE_DOWN) {
        // removeCallbacks(mPendingCheckForTap);
        // }
        // }
        break;
    }

    case MotionEvent.ACTION_MOVE: {
        int pointerIndex = ev.findPointerIndex(mActivePointerId);
        if (pointerIndex == -1) {
            pointerIndex = 0;
            mActivePointerId = ev.getPointerId(pointerIndex);
        }
        final int y = (int) ev.getY(pointerIndex);
        switch (mTouchMode) {
        case TOUCH_MODE_DOWN:
        case TOUCH_MODE_TAP:
        case TOUCH_MODE_DONE_WAITING:
            // Check if we have moved far enough that it looks more like a
            // scroll than a tap
            startScrollIfNeeded(y);
            break;
        case TOUCH_MODE_SCROLL:
        case TOUCH_MODE_OVERSCROLL:
            scrollIfNeeded(y);
            break;
        }
        break;
    }

    case MotionEvent.ACTION_UP: {
        switch (mTouchMode) {
        case TOUCH_MODE_DOWN:
        case TOUCH_MODE_TAP:
        case TOUCH_MODE_DONE_WAITING:
            final int motionPosition = mMotionPosition;
            final View child = getChildAt(motionPosition - mFirstPosition);

            final float x = ev.getX();
            final boolean inList = x > mListPadding.left && x < getWidth() - mListPadding.right;

            if (child != null && !child.hasFocusable() && inList) {
                if (mTouchMode != TOUCH_MODE_DOWN) {
                    child.setPressed(false);
                }

                if (mPerformClick == null) {
                    mPerformClick = new PerformClick();
                }

                final AbsListView.PerformClick performClick = mPerformClick;
                performClick.mClickMotionPosition = motionPosition;
                performClick.rememberWindowAttachCount();

                mResurrectToPosition = motionPosition;

                if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) {
                    final Handler handler = getHandler();
                    if (handler != null) {
                        handler.removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ? mPendingCheckForTap
                                : mPendingCheckForLongPress);
                    }
                    mLayoutMode = LAYOUT_NORMAL;
                    if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
                        mTouchMode = TOUCH_MODE_TAP;
                        setSelectedPositionInt(mMotionPosition);
                        layoutChildren();
                        child.setPressed(true);
                        positionSelector(mMotionPosition, child);
                        setPressed(true);
                        if (mSelector != null) {
                            Drawable d = mSelector.getCurrent();
                            if (d != null && d instanceof TransitionDrawable) {
                                ((TransitionDrawable) d).resetTransition();
                            }
                        }
                        if (mTouchModeReset != null) {
                            removeCallbacks(mTouchModeReset);
                        }
                        mTouchModeReset = new Runnable() {
                            @Override
                            public void run() {
                                mTouchMode = TOUCH_MODE_REST;
                                child.setPressed(false);
                                setPressed(false);
                                if (!mDataChanged) {
                                    performClick.run();
                                }
                            }
                        };
                        postDelayed(mTouchModeReset, ViewConfiguration.getPressedStateDuration());
                    } else {
                        mTouchMode = TOUCH_MODE_REST;
                        updateSelectorState();
                    }
                    return true;
                } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
                    performClick.run();
                }
            }
            mTouchMode = TOUCH_MODE_REST;
            updateSelectorState();
            break;
        case TOUCH_MODE_SCROLL:
            final int childCount = getChildCount();
            if (childCount > 0) {
                final int firstChildTop = getChildAt(0).getTop();
                final int lastChildBottom = getChildAt(childCount - 1).getBottom();
                final int contentTop = mListPadding.top;
                final int contentBottom = getHeight() - mListPadding.bottom;
                if (mFirstPosition == 0 && firstChildTop >= contentTop
                        && mFirstPosition + childCount < mItemCount
                        && lastChildBottom <= getHeight() - contentBottom) {
                    mTouchMode = TOUCH_MODE_REST;
                    reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                } else {
                    final VelocityTracker velocityTracker = mVelocityTracker;
                    velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);

                    final int initialVelocity = (int) (velocityTracker.getYVelocity(mActivePointerId)
                            * mVelocityScale);
                    // Fling if we have enough velocity and we aren't at a
                    // boundary.
                    // Since we can potentially overfling more than we can
                    // overscroll, don't
                    // allow the weird behavior where you can scroll to a
                    // boundary then
                    // fling further.
                    if (Math.abs(initialVelocity) > mMinimumVelocity
                            && !((mFirstPosition == 0 && firstChildTop == contentTop - mOverscrollDistance)
                                    || (mFirstPosition + childCount == mItemCount
                                            && lastChildBottom == contentBottom + mOverscrollDistance))) {
                        if (mFlingRunnable == null) {
                            mFlingRunnable = new FlingRunnable();
                        }
                        reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);

                        mFlingRunnable.start(-initialVelocity);
                    } else {
                        mTouchMode = TOUCH_MODE_REST;
                        reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                        if (mFlingRunnable != null) {
                            mFlingRunnable.endFling();
                        }
                        if (mPositionScroller != null) {
                            mPositionScroller.stop();
                        }
                    }
                }
            } else {
                mTouchMode = TOUCH_MODE_REST;
                reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
            }
            break;

        case TOUCH_MODE_OVERSCROLL:
            if (mFlingRunnable == null) {
                mFlingRunnable = new FlingRunnable();
            }
            final VelocityTracker velocityTracker = mVelocityTracker;
            velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);

            reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
            if (Math.abs(initialVelocity) > mMinimumVelocity) {
                mFlingRunnable.startOverfling(-initialVelocity);
            } else {
                mFlingRunnable.startSpringback();
            }

            break;
        }

        setPressed(false);

        // Need to redraw since we probably aren't drawing the selector
        // anymore
        invalidate();

        final Handler handler = getHandler();
        if (handler != null) {
            handler.removeCallbacks(mPendingCheckForLongPress);
        }

        recycleVelocityTracker();

        mActivePointerId = INVALID_POINTER;

        if (PROFILE_SCROLLING) {
            if (mScrollProfilingStarted) {
                Debug.stopMethodTracing();
                mScrollProfilingStarted = false;
            }
        }
        break;
    }

    case MotionEvent.ACTION_CANCEL: {
        switch (mTouchMode) {
        case TOUCH_MODE_OVERSCROLL:
            if (mFlingRunnable == null) {
                mFlingRunnable = new FlingRunnable();
            }
            mFlingRunnable.startSpringback();
            break;

        case TOUCH_MODE_OVERFLING:
            // Do nothing - let it play out.
            break;

        default:
            mTouchMode = TOUCH_MODE_REST;
            setPressed(false);
            View motionView = this.getChildAt(mMotionPosition - mFirstPosition);
            if (motionView != null) {
                motionView.setPressed(false);
            }
            clearScrollingCache();

            final Handler handler = getHandler();
            if (handler != null) {
                handler.removeCallbacks(mPendingCheckForLongPress);
            }

            recycleVelocityTracker();
        }

        mActivePointerId = INVALID_POINTER;
        break;
    }

    case MotionEvent.ACTION_POINTER_UP: {
        onSecondaryPointerUp(ev);
        final int x = mMotionX;
        final int y = mMotionY;
        final int motionPosition = pointToPosition(x, y);
        if (motionPosition >= 0) {
            // Remember where the motion event started
            v = getChildAt(motionPosition - mFirstPosition);
            mMotionViewOriginalTop = v.getTop();
            mMotionPosition = motionPosition;
        }
        mLastY = y;
        break;
    }

    case MotionEvent.ACTION_POINTER_DOWN: {
        // New pointers take over dragging duties
        final int index = ev.getActionIndex();
        final int id = ev.getPointerId(index);
        final int x = (int) ev.getX(index);
        final int y = (int) ev.getY(index);
        mMotionCorrection = 0;
        mActivePointerId = id;
        mMotionX = x;
        mMotionY = y;
        final int motionPosition = pointToPosition(x, y);
        if (motionPosition >= 0) {
            // Remember where the motion event started
            v = getChildAt(motionPosition - mFirstPosition);
            mMotionViewOriginalTop = v.getTop();
            mMotionPosition = motionPosition;
        }
        mLastY = y;
        break;
    }
    }

    return true;
}

From source file:com.appunite.list.AbsHorizontalListView.java

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (!isEnabled()) {
        // A disabled view that is clickable still consumes the touch
        // events, it just doesn't respond to them.
        return isClickable() || isLongClickable();
    }//from  w  w w  . j  ava2 s .c  o  m

    if (mPositionScroller != null) {
        mPositionScroller.stop();
    }

    if (!mIsAttached) {
        // Something isn't right.
        // Since we rely on being attached to get data set change notifications,
        // don't risk doing anything where we might try to resync and find things
        // in a bogus state.
        return false;
    }

    final int action = ev.getAction();

    View v;

    initVelocityTrackerIfNotExists();
    mVelocityTracker.addMovement(ev);

    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN: {
        switch (mTouchMode) {
        case TOUCH_MODE_OVERFLING: {
            mFlingRunnable.endFling();
            if (mPositionScroller != null) {
                mPositionScroller.stop();
            }
            mTouchMode = TOUCH_MODE_OVERSCROLL;
            mMotionX = mLastX = (int) ev.getX();
            mMotionY = (int) ev.getY();
            mMotionCorrection = 0;
            mActivePointerId = ev.getPointerId(0);
            mDirection = 0;
            break;
        }

        default: {
            mActivePointerId = ev.getPointerId(0);
            final int x = (int) ev.getX();
            final int y = (int) ev.getY();
            int motionPosition = pointToPosition(x, y);
            if (!mDataChanged) {
                if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0)
                        && (getAdapter().isEnabled(motionPosition))) {
                    // User clicked on an actual view (and was not stopping a fling).
                    // It might be a click or a scroll. Assume it is a click until
                    // proven otherwise
                    mTouchMode = TOUCH_MODE_DOWN;
                    // FIXME Debounce
                    if (mPendingCheckForTap == null) {
                        mPendingCheckForTap = new CheckForTap();
                    }
                    postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
                } else {
                    if (mTouchMode == TOUCH_MODE_FLING) {
                        // Stopped a fling. It is a scroll.
                        createScrollingCache();
                        mTouchMode = TOUCH_MODE_SCROLL;
                        mMotionCorrection = 0;
                        motionPosition = findMotionCol(x);
                        mFlingRunnable.flywheelTouch();
                    }
                }
            }

            if (motionPosition >= 0) {
                // Remember where the motion event started
                v = getChildAt(motionPosition - mFirstPosition);
                mMotionViewOriginalLeft = v.getLeft();
            }
            mMotionX = x;
            mMotionY = y;
            mMotionPosition = motionPosition;
            mLastX = Integer.MIN_VALUE;
            break;
        }
        }

        if (performButtonActionOnTouchDownUnhide(ev)) {
            if (mTouchMode == TOUCH_MODE_DOWN) {
                removeCallbacks(mPendingCheckForTap);
            }
        }
        break;
    }

    case MotionEvent.ACTION_MOVE: {
        int pointerIndex = ev.findPointerIndex(mActivePointerId);
        if (pointerIndex == -1) {
            pointerIndex = 0;
            mActivePointerId = ev.getPointerId(pointerIndex);
        }
        final int x = (int) ev.getX(pointerIndex);

        if (mDataChanged) {
            // Re-sync everything if data has been changed
            // since the scroll operation can query the adapter.
            layoutChildren();
        }

        switch (mTouchMode) {
        case TOUCH_MODE_DOWN:
        case TOUCH_MODE_TAP:
        case TOUCH_MODE_DONE_WAITING:
            // Check if we have moved far enough that it looks more like a
            // scroll than a tap
            startScrollIfNeeded(x);
            break;
        case TOUCH_MODE_SCROLL:
        case TOUCH_MODE_OVERSCROLL:
            scrollIfNeeded(x);
            break;
        }
        break;
    }

    case MotionEvent.ACTION_UP: {
        switch (mTouchMode) {
        case TOUCH_MODE_DOWN:
        case TOUCH_MODE_TAP:
        case TOUCH_MODE_DONE_WAITING:
            final int motionPosition = mMotionPosition;
            final View child = getChildAt(motionPosition - mFirstPosition);

            final float y = ev.getY();
            final boolean inList = y > mListPadding.top && y < getHeight() - mListPadding.bottom;

            if (child != null && !child.hasFocusable() && inList) {
                if (mTouchMode != TOUCH_MODE_DOWN) {
                    child.setPressed(false);
                }

                if (mPerformClick == null) {
                    mPerformClick = new PerformClick();
                }

                final AbsHorizontalListView.PerformClick performClick = mPerformClick;
                performClick.mClickMotionPosition = motionPosition;
                performClick.rememberWindowAttachCount();

                mResurrectToPosition = motionPosition;

                if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) {
                    final Handler handler = getHandler();
                    if (handler != null) {
                        handler.removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ? mPendingCheckForTap
                                : mPendingCheckForLongPress);
                    }
                    mLayoutMode = LAYOUT_NORMAL;
                    if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
                        mTouchMode = TOUCH_MODE_TAP;
                        setSelectedPositionInt(mMotionPosition);
                        layoutChildren();
                        child.setPressed(true);
                        positionSelector(mMotionPosition, child);
                        setPressed(true);
                        if (mSelector != null) {
                            Drawable d = mSelector.getCurrent();
                            if (d != null && d instanceof TransitionDrawable) {
                                ((TransitionDrawable) d).resetTransition();
                            }
                        }
                        if (mTouchModeReset != null) {
                            removeCallbacks(mTouchModeReset);
                        }
                        mTouchModeReset = new Runnable() {
                            @Override
                            public void run() {
                                mTouchModeReset = null;
                                mTouchMode = TOUCH_MODE_REST;
                                child.setPressed(false);
                                setPressed(false);
                                if (!mDataChanged) {
                                    performClick.run();
                                }
                            }
                        };
                        postDelayed(mTouchModeReset, ViewConfiguration.getPressedStateDuration());
                    } else {
                        mTouchMode = TOUCH_MODE_REST;
                        updateSelectorState();
                    }
                    return true;
                } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
                    performClick.run();
                }
            }
            mTouchMode = TOUCH_MODE_REST;
            updateSelectorState();
            break;
        case TOUCH_MODE_SCROLL:
            final int childCount = getChildCount();
            if (childCount > 0) {
                final int firstChildLeft = getChildAt(0).getLeft();
                final int lastChildRight = getChildAt(childCount - 1).getRight();
                final int contentLeft = mListPadding.left;
                final int contentRight = getWidth() - mListPadding.right;
                if (mFirstPosition == 0 && firstChildLeft >= contentLeft
                        && mFirstPosition + childCount < mItemCount
                        && lastChildRight <= getWidth() - contentRight) {
                    mTouchMode = TOUCH_MODE_REST;
                    reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                } else {
                    final VelocityTracker velocityTracker = mVelocityTracker;
                    velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);

                    final int initialVelocity = (int) (velocityTracker.getXVelocity(mActivePointerId)
                            * mVelocityScale);
                    // Fling if we have enough velocity and we aren't at a boundary.
                    // Since we can potentially overfling more than we can overscroll, don't
                    // allow the weird behavior where you can scroll to a boundary then
                    // fling further.
                    if (Math.abs(initialVelocity) > mMinimumVelocity
                            && !((mFirstPosition == 0 && firstChildLeft == contentLeft - mOverscrollDistance)
                                    || (mFirstPosition + childCount == mItemCount
                                            && lastChildRight == contentRight + mOverscrollDistance))) {
                        if (mFlingRunnable == null) {
                            mFlingRunnable = new FlingRunnable();
                        }
                        reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);

                        mFlingRunnable.start(-initialVelocity);
                    } else {
                        mTouchMode = TOUCH_MODE_REST;
                        reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                        if (mFlingRunnable != null) {
                            mFlingRunnable.endFling();
                        }
                        if (mPositionScroller != null) {
                            mPositionScroller.stop();
                        }
                    }
                }
            } else {
                mTouchMode = TOUCH_MODE_REST;
                reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
            }
            break;

        case TOUCH_MODE_OVERSCROLL:
            if (mFlingRunnable == null) {
                mFlingRunnable = new FlingRunnable();
            }
            final VelocityTracker velocityTracker = mVelocityTracker;
            velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            final int initialVelocity = (int) velocityTracker.getXVelocity(mActivePointerId);

            reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
            if (Math.abs(initialVelocity) > mMinimumVelocity) {
                mFlingRunnable.startOverfling(-initialVelocity);
            } else {
                mFlingRunnable.startSpringback();
            }

            break;
        }

        setPressed(false);

        if (mEdgeGlowLeft != null) {
            mEdgeGlowLeft.onRelease();
            mEdgeGlowRight.onRelease();
        }

        // Need to redraw since we probably aren't drawing the selector anymore
        invalidate();

        final Handler handler = getHandler();
        if (handler != null) {
            handler.removeCallbacks(mPendingCheckForLongPress);
        }

        recycleVelocityTracker();

        mActivePointerId = INVALID_POINTER;

        if (PROFILE_SCROLLING) {
            if (mScrollProfilingStarted) {
                Debug.stopMethodTracing();
                mScrollProfilingStarted = false;
            }
        }

        // FIXME not needed bacaues we could not implement strict span (j.m.)
        //            if (mScrollStrictSpan != null) {
        //                mScrollStrictSpan.finish();
        //                mScrollStrictSpan = null;
        //            }
        break;
    }

    case MotionEvent.ACTION_CANCEL: {
        switch (mTouchMode) {
        case TOUCH_MODE_OVERSCROLL:
            if (mFlingRunnable == null) {
                mFlingRunnable = new FlingRunnable();
            }
            mFlingRunnable.startSpringback();
            break;

        case TOUCH_MODE_OVERFLING:
            // Do nothing - let it play out.
            break;

        default:
            mTouchMode = TOUCH_MODE_REST;
            setPressed(false);
            View motionView = this.getChildAt(mMotionPosition - mFirstPosition);
            if (motionView != null) {
                motionView.setPressed(false);
            }
            clearScrollingCache();

            final Handler handler = getHandler();
            if (handler != null) {
                handler.removeCallbacks(mPendingCheckForLongPress);
            }

            recycleVelocityTracker();
        }

        if (mEdgeGlowLeft != null) {
            mEdgeGlowLeft.onRelease();
            mEdgeGlowRight.onRelease();
        }
        mActivePointerId = INVALID_POINTER;
        break;
    }

    case MotionEvent.ACTION_POINTER_UP: {
        onSecondaryPointerUp(ev);
        final int x = mMotionX;
        final int y = mMotionY;
        final int motionPosition = pointToPosition(x, y);
        if (motionPosition >= 0) {
            // Remember where the motion event started
            v = getChildAt(motionPosition - mFirstPosition);
            mMotionViewOriginalLeft = v.getLeft();
            mMotionPosition = motionPosition;
        }
        mLastX = x;
        break;
    }

    case MotionEvent.ACTION_POINTER_DOWN: {
        // New pointers take over dragging duties
        final int index = ev.getActionIndex();
        final int id = ev.getPointerId(index);
        final int x = (int) ev.getX(index);
        final int y = (int) ev.getY(index);
        mMotionCorrection = 0;
        mActivePointerId = id;
        mMotionX = x;
        mMotionY = y;
        final int motionPosition = pointToPosition(x, y);
        if (motionPosition >= 0) {
            // Remember where the motion event started
            v = getChildAt(motionPosition - mFirstPosition);
            mMotionViewOriginalLeft = v.getLeft();
            mMotionPosition = motionPosition;
        }
        mLastX = x;
        break;
    }
    }

    return true;
}

From source file:com.appunite.list.AbsListView.java

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (!isEnabled()) {
        // A disabled view that is clickable still consumes the touch
        // events, it just doesn't respond to them.
        return isClickable() || isLongClickable();
    }/*from  w w w. jav  a 2 s  . c o m*/

    if (mPositionScroller != null) {
        mPositionScroller.stop();
    }

    if (!mIsAttached) {
        // Something isn't right.
        // Since we rely on being attached to get data set change notifications,
        // don't risk doing anything where we might try to resync and find things
        // in a bogus state.
        return false;
    }

    if (mFastScroller != null) {
        boolean intercepted = mFastScroller.onTouchEvent(ev);
        if (intercepted) {
            return true;
        }
    }

    final int action = ev.getAction();

    View v;

    initVelocityTrackerIfNotExists();
    mVelocityTracker.addMovement(ev);

    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN: {
        switch (mTouchMode) {
        case TOUCH_MODE_OVERFLING: {
            mFlingRunnable.endFling();
            if (mPositionScroller != null) {
                mPositionScroller.stop();
            }
            mTouchMode = TOUCH_MODE_OVERSCROLL;
            mMotionX = (int) ev.getX();
            mMotionY = mLastY = (int) ev.getY();
            mMotionCorrection = 0;
            mActivePointerId = ev.getPointerId(0);
            mDirection = 0;
            break;
        }

        default: {
            mActivePointerId = ev.getPointerId(0);
            final int x = (int) ev.getX();
            final int y = (int) ev.getY();
            int motionPosition = pointToPosition(x, y);
            if (!mDataChanged) {
                if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0)
                        && (getAdapter().isEnabled(motionPosition))) {
                    // User clicked on an actual view (and was not stopping a fling).
                    // It might be a click or a scroll. Assume it is a click until
                    // proven otherwise
                    mTouchMode = TOUCH_MODE_DOWN;
                    // FIXME Debounce
                    if (mPendingCheckForTap == null) {
                        mPendingCheckForTap = new CheckForTap();
                    }
                    postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
                } else {
                    if (mTouchMode == TOUCH_MODE_FLING) {
                        // Stopped a fling. It is a scroll.
                        createScrollingCache();
                        mTouchMode = TOUCH_MODE_SCROLL;
                        mMotionCorrection = 0;
                        motionPosition = findMotionRow(y);
                        mFlingRunnable.flywheelTouch();
                    }
                }
            }

            if (motionPosition >= 0) {
                // Remember where the motion event started
                v = getChildAt(motionPosition - mFirstPosition);
                mMotionViewOriginalTop = v.getTop();
            }
            mMotionX = x;
            mMotionY = y;
            mMotionPosition = motionPosition;
            mLastY = Integer.MIN_VALUE;
            break;
        }
        }

        if (performButtonActionOnTouchDownUnhide(ev)) {
            if (mTouchMode == TOUCH_MODE_DOWN) {
                removeCallbacks(mPendingCheckForTap);
            }
        }
        break;
    }

    case MotionEvent.ACTION_MOVE: {
        int pointerIndex = ev.findPointerIndex(mActivePointerId);
        if (pointerIndex == -1) {
            pointerIndex = 0;
            mActivePointerId = ev.getPointerId(pointerIndex);
        }
        final int y = (int) ev.getY(pointerIndex);

        if (mDataChanged) {
            // Re-sync everything if data has been changed
            // since the scroll operation can query the adapter.
            layoutChildren();
        }

        switch (mTouchMode) {
        case TOUCH_MODE_DOWN:
        case TOUCH_MODE_TAP:
        case TOUCH_MODE_DONE_WAITING:
            // Check if we have moved far enough that it looks more like a
            // scroll than a tap
            startScrollIfNeeded(y);
            break;
        case TOUCH_MODE_SCROLL:
        case TOUCH_MODE_OVERSCROLL:
            scrollIfNeeded(y);
            break;
        }
        break;
    }

    case MotionEvent.ACTION_UP: {
        switch (mTouchMode) {
        case TOUCH_MODE_DOWN:
        case TOUCH_MODE_TAP:
        case TOUCH_MODE_DONE_WAITING:
            final int motionPosition = mMotionPosition;
            final View child = getChildAt(motionPosition - mFirstPosition);

            final float x = ev.getX();
            final boolean inList = x > mListPadding.left && x < getWidth() - mListPadding.right;

            if (child != null && !child.hasFocusable() && inList) {
                if (mTouchMode != TOUCH_MODE_DOWN) {
                    child.setPressed(false);
                }

                if (mPerformClick == null) {
                    mPerformClick = new PerformClick();
                }

                final AbsListView.PerformClick performClick = mPerformClick;
                performClick.mClickMotionPosition = motionPosition;
                performClick.rememberWindowAttachCount();

                mResurrectToPosition = motionPosition;

                if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) {
                    final Handler handler = getHandler();
                    if (handler != null) {
                        handler.removeCallbacks(mTouchMode == TOUCH_MODE_DOWN ? mPendingCheckForTap
                                : mPendingCheckForLongPress);
                    }
                    mLayoutMode = LAYOUT_NORMAL;
                    if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
                        mTouchMode = TOUCH_MODE_TAP;
                        setSelectedPositionInt(mMotionPosition);
                        layoutChildren();
                        child.setPressed(true);
                        positionSelector(mMotionPosition, child);
                        setPressed(true);
                        if (mSelector != null) {
                            Drawable d = mSelector.getCurrent();
                            if (d != null && d instanceof TransitionDrawable) {
                                ((TransitionDrawable) d).resetTransition();
                            }
                        }
                        if (mTouchModeReset != null) {
                            removeCallbacks(mTouchModeReset);
                        }
                        mTouchModeReset = new Runnable() {
                            @Override
                            public void run() {
                                mTouchModeReset = null;
                                mTouchMode = TOUCH_MODE_REST;
                                child.setPressed(false);
                                setPressed(false);
                                if (!mDataChanged) {
                                    performClick.run();
                                }
                            }
                        };
                        postDelayed(mTouchModeReset, ViewConfiguration.getPressedStateDuration());
                    } else {
                        mTouchMode = TOUCH_MODE_REST;
                        updateSelectorState();
                    }
                    return true;
                } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
                    performClick.run();
                }
            }
            mTouchMode = TOUCH_MODE_REST;
            updateSelectorState();
            break;
        case TOUCH_MODE_SCROLL:
            final int childCount = getChildCount();
            if (childCount > 0) {
                final int firstChildTop = getChildAt(0).getTop();
                final int lastChildBottom = getChildAt(childCount - 1).getBottom();
                final int contentTop = mListPadding.top;
                final int contentBottom = getHeight() - mListPadding.bottom;
                if (mFirstPosition == 0 && firstChildTop >= contentTop
                        && mFirstPosition + childCount < mItemCount
                        && lastChildBottom <= getHeight() - contentBottom) {
                    mTouchMode = TOUCH_MODE_REST;
                    reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                } else {
                    final VelocityTracker velocityTracker = mVelocityTracker;
                    velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);

                    final int initialVelocity = (int) (velocityTracker.getYVelocity(mActivePointerId)
                            * mVelocityScale);
                    // Fling if we have enough velocity and we aren't at a boundary.
                    // Since we can potentially overfling more than we can overscroll, don't
                    // allow the weird behavior where you can scroll to a boundary then
                    // fling further.
                    if (Math.abs(initialVelocity) > mMinimumVelocity
                            && !((mFirstPosition == 0 && firstChildTop == contentTop - mOverscrollDistance)
                                    || (mFirstPosition + childCount == mItemCount
                                            && lastChildBottom == contentBottom + mOverscrollDistance))) {
                        if (mFlingRunnable == null) {
                            mFlingRunnable = new FlingRunnable();
                        }
                        reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);

                        mFlingRunnable.start(-initialVelocity);
                    } else {
                        mTouchMode = TOUCH_MODE_REST;
                        reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                        if (mFlingRunnable != null) {
                            mFlingRunnable.endFling();
                        }
                        if (mPositionScroller != null) {
                            mPositionScroller.stop();
                        }
                    }
                }
            } else {
                mTouchMode = TOUCH_MODE_REST;
                reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
            }
            break;

        case TOUCH_MODE_OVERSCROLL:
            if (mFlingRunnable == null) {
                mFlingRunnable = new FlingRunnable();
            }
            final VelocityTracker velocityTracker = mVelocityTracker;
            velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            final int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);

            reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
            if (Math.abs(initialVelocity) > mMinimumVelocity) {
                mFlingRunnable.startOverfling(-initialVelocity);
            } else {
                mFlingRunnable.startSpringback();
            }

            break;
        }

        setPressed(false);

        if (mEdgeGlowTop != null) {
            mEdgeGlowTop.onRelease();
            mEdgeGlowBottom.onRelease();
        }

        // Need to redraw since we probably aren't drawing the selector anymore
        invalidate();

        final Handler handler = getHandler();
        if (handler != null) {
            handler.removeCallbacks(mPendingCheckForLongPress);
        }

        recycleVelocityTracker();

        mActivePointerId = INVALID_POINTER;

        if (PROFILE_SCROLLING) {
            if (mScrollProfilingStarted) {
                Debug.stopMethodTracing();
                mScrollProfilingStarted = false;
            }
        }

        // FIXME not needed bacaues we could not implement strict span (j.m.)
        //            if (mScrollStrictSpan != null) {
        //                mScrollStrictSpan.finish();
        //                mScrollStrictSpan = null;
        //            }
        break;
    }

    case MotionEvent.ACTION_CANCEL: {
        switch (mTouchMode) {
        case TOUCH_MODE_OVERSCROLL:
            if (mFlingRunnable == null) {
                mFlingRunnable = new FlingRunnable();
            }
            mFlingRunnable.startSpringback();
            break;

        case TOUCH_MODE_OVERFLING:
            // Do nothing - let it play out.
            break;

        default:
            mTouchMode = TOUCH_MODE_REST;
            setPressed(false);
            View motionView = this.getChildAt(mMotionPosition - mFirstPosition);
            if (motionView != null) {
                motionView.setPressed(false);
            }
            clearScrollingCache();

            final Handler handler = getHandler();
            if (handler != null) {
                handler.removeCallbacks(mPendingCheckForLongPress);
            }

            recycleVelocityTracker();
        }

        if (mEdgeGlowTop != null) {
            mEdgeGlowTop.onRelease();
            mEdgeGlowBottom.onRelease();
        }
        mActivePointerId = INVALID_POINTER;
        break;
    }

    case MotionEvent.ACTION_POINTER_UP: {
        onSecondaryPointerUp(ev);
        final int x = mMotionX;
        final int y = mMotionY;
        final int motionPosition = pointToPosition(x, y);
        if (motionPosition >= 0) {
            // Remember where the motion event started
            v = getChildAt(motionPosition - mFirstPosition);
            mMotionViewOriginalTop = v.getTop();
            mMotionPosition = motionPosition;
        }
        mLastY = y;
        break;
    }

    case MotionEvent.ACTION_POINTER_DOWN: {
        // New pointers take over dragging duties
        final int index = MotionEventCompat.getActionIndex(ev);
        final int id = ev.getPointerId(index);
        final int x = (int) ev.getX(index);
        final int y = (int) ev.getY(index);
        mMotionCorrection = 0;
        mActivePointerId = id;
        mMotionX = x;
        mMotionY = y;
        final int motionPosition = pointToPosition(x, y);
        if (motionPosition >= 0) {
            // Remember where the motion event started
            v = getChildAt(motionPosition - mFirstPosition);
            mMotionViewOriginalTop = v.getTop();
            mMotionPosition = motionPosition;
        }
        mLastY = y;
        break;
    }
    }

    return true;
}

From source file:com.datarita.ultimatecamera.turu.views.TwoWayView.java

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (!isEnabled()) {
        // A disabled view that is clickable still consumes the touch
        // events, it just doesn't respond to them.
        return isClickable() || isLongClickable();
    }/*from  w  w  w  .ja  va2  s.  com*/

    if (!mIsAttached) {
        return false;
    }

    boolean needsInvalidate = false;

    initVelocityTrackerIfNotExists();
    mVelocityTracker.addMovement(ev);

    final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
    switch (action) {
    case MotionEvent.ACTION_DOWN: {
        if (mDataChanged) {
            break;
        }

        mVelocityTracker.clear();
        mScroller.abortAnimation();

        final float x = ev.getX();
        final float y = ev.getY();

        mLastTouchPos = (mIsVertical ? y : x);

        int motionPosition = pointToPosition((int) x, (int) y);

        mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
        mTouchRemainderPos = 0;

        if (mDataChanged) {
            break;
        }

        if (mTouchMode == TOUCH_MODE_FLINGING) {
            mTouchMode = TOUCH_MODE_DRAGGING;
            reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
            motionPosition = findMotionRowOrColumn((int) mLastTouchPos);
            return true;
        } else if (mMotionPosition >= 0 && mAdapter.isEnabled(mMotionPosition)) {
            mTouchMode = TOUCH_MODE_DOWN;
            triggerCheckForTap();
        }

        mMotionPosition = motionPosition;

        break;
    }

    case MotionEvent.ACTION_MOVE: {
        final int index = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
        if (index < 0) {
            Log.e(LOGTAG, "onInterceptTouchEvent could not find pointer with id " + mActivePointerId
                    + " - did TwoWayView receive an inconsistent " + "event stream?");
            return false;
        }

        final float pos;
        if (mIsVertical) {
            pos = MotionEventCompat.getY(ev, index);
        } else {
            pos = MotionEventCompat.getX(ev, index);
        }

        if (mDataChanged) {
            // Re-sync everything if data has been changed
            // since the scroll operation can query the mAdapter.
            layoutChildren();
        }

        final float diff = pos - mLastTouchPos + mTouchRemainderPos;
        final int delta = (int) diff;
        mTouchRemainderPos = diff - delta;

        switch (mTouchMode) {
        case TOUCH_MODE_DOWN:
        case TOUCH_MODE_TAP:
        case TOUCH_MODE_DONE_WAITING:
            // Check if we have moved far enough that it looks more like a
            // scroll than a tap
            maybeStartScrolling(delta);
            break;

        case TOUCH_MODE_DRAGGING:
        case TOUCH_MODE_OVERSCROLL:
            mLastTouchPos = pos;
            maybeScroll(delta);
            break;
        }

        break;
    }

    case MotionEvent.ACTION_CANCEL:
        cancelCheckForTap();
        mTouchMode = TOUCH_MODE_REST;
        reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);

        setPressed(false);
        View motionView = this.getChildAt(mMotionPosition - mFirstPosition);
        if (motionView != null) {
            motionView.setPressed(false);
        }

        if (mStartEdge != null && mEndEdge != null) {
            needsInvalidate = mStartEdge.onRelease() | mEndEdge.onRelease();
        }

        recycleVelocityTracker();

        break;

    case MotionEvent.ACTION_UP: {
        switch (mTouchMode) {
        case TOUCH_MODE_DOWN:
        case TOUCH_MODE_TAP:
        case TOUCH_MODE_DONE_WAITING: {
            final int motionPosition = mMotionPosition;
            final View child = getChildAt(motionPosition - mFirstPosition);

            final float x = ev.getX();
            final float y = ev.getY();

            boolean inList = false;
            if (mIsVertical) {
                inList = x > getPaddingLeft() && x < getWidth() - getPaddingRight();
            } else {
                inList = y > getPaddingTop() && y < getHeight() - getPaddingBottom();
            }

            if (child != null && !child.hasFocusable() && inList) {
                if (mTouchMode != TOUCH_MODE_DOWN) {
                    child.setPressed(false);
                }

                if (mPerformClick == null) {
                    mPerformClick = new PerformClick();
                }

                final PerformClick performClick = mPerformClick;
                performClick.mClickMotionPosition = motionPosition;
                performClick.rememberWindowAttachCount();

                mResurrectToPosition = motionPosition;

                if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) {
                    if (mTouchMode == TOUCH_MODE_DOWN) {
                        cancelCheckForTap();
                    } else {
                        cancelCheckForLongPress();
                    }

                    mLayoutMode = LAYOUT_NORMAL;

                    if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
                        mTouchMode = TOUCH_MODE_TAP;

                        setPressed(true);
                        positionSelector(mMotionPosition, child);
                        child.setPressed(true);

                        if (mSelector != null) {
                            Drawable d = mSelector.getCurrent();
                            if (d != null && d instanceof TransitionDrawable) {
                                ((TransitionDrawable) d).resetTransition();
                            }
                        }

                        if (mTouchModeReset != null) {
                            removeCallbacks(mTouchModeReset);
                        }

                        mTouchModeReset = new Runnable() {
                            @Override
                            public void run() {
                                mTouchMode = TOUCH_MODE_REST;

                                setPressed(false);
                                child.setPressed(false);

                                if (!mDataChanged) {
                                    performClick.run();
                                }

                                mTouchModeReset = null;
                            }
                        };

                        postDelayed(mTouchModeReset, ViewConfiguration.getPressedStateDuration());
                    } else {
                        mTouchMode = TOUCH_MODE_REST;
                        updateSelectorState();
                    }
                } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
                    performClick.run();
                }
            }

            mTouchMode = TOUCH_MODE_REST;
            updateSelectorState();

            break;
        }

        case TOUCH_MODE_DRAGGING:
            if (contentFits()) {
                mTouchMode = TOUCH_MODE_REST;
                reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                break;
            }

            mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);

            final float velocity;
            if (mIsVertical) {
                velocity = VelocityTrackerCompat.getYVelocity(mVelocityTracker, mActivePointerId);
            } else {
                velocity = VelocityTrackerCompat.getXVelocity(mVelocityTracker, mActivePointerId);
            }

            if (Math.abs(velocity) >= mFlingVelocity) {
                mTouchMode = TOUCH_MODE_FLINGING;
                reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);

                mScroller.fling(0, 0, (int) (mIsVertical ? 0 : velocity), (int) (mIsVertical ? velocity : 0),
                        (mIsVertical ? 0 : Integer.MIN_VALUE), (mIsVertical ? 0 : Integer.MAX_VALUE),
                        (mIsVertical ? Integer.MIN_VALUE : 0), (mIsVertical ? Integer.MAX_VALUE : 0));

                mLastTouchPos = 0;
                needsInvalidate = true;
            } else {
                mTouchMode = TOUCH_MODE_REST;
                reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
            }

            break;

        case TOUCH_MODE_OVERSCROLL:
            mTouchMode = TOUCH_MODE_REST;
            reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
            break;
        }

        cancelCheckForTap();
        cancelCheckForLongPress();
        setPressed(false);

        if (mStartEdge != null && mEndEdge != null) {
            needsInvalidate |= mStartEdge.onRelease() | mEndEdge.onRelease();
        }

        recycleVelocityTracker();

        break;
    }
    }

    if (needsInvalidate) {
        ViewCompat.postInvalidateOnAnimation(this);
    }

    return true;
}

From source file:com.boutline.sports.helpers.TwoWayView.java

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (!isEnabled()) {
        // A disabled view that is clickable still consumes the touch
        // events, it just doesn't respond to them.
        return isClickable() || isLongClickable();
    }//from w w  w  .  j a va2s .  c o m

    if (!mIsAttached || mAdapter == null) {
        return false;
    }

    boolean needsInvalidate = false;

    initVelocityTrackerIfNotExists();
    mVelocityTracker.addMovement(ev);

    final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
    switch (action) {
    case MotionEvent.ACTION_DOWN: {
        if (mDataChanged) {
            break;
        }

        mVelocityTracker.clear();
        mScroller.abortAnimation();

        final float x = ev.getX();
        final float y = ev.getY();

        mLastTouchPos = (mIsVertical ? y : x);

        int motionPosition = pointToPosition((int) x, (int) y);

        mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
        mTouchRemainderPos = 0;

        if (mDataChanged) {
            break;
        }

        if (mTouchMode == TOUCH_MODE_FLINGING) {
            mTouchMode = TOUCH_MODE_DRAGGING;
            reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
            motionPosition = findMotionRowOrColumn((int) mLastTouchPos);
            return true;
        } else if (mMotionPosition >= 0 && mAdapter.isEnabled(mMotionPosition)) {
            mTouchMode = TOUCH_MODE_DOWN;
            triggerCheckForTap();
        }

        mMotionPosition = motionPosition;

        break;
    }

    case MotionEvent.ACTION_MOVE: {
        final int index = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
        if (index < 0) {
            Log.e(LOGTAG, "onInterceptTouchEvent could not find pointer with id " + mActivePointerId
                    + " - did TwoWayView receive an inconsistent " + "event stream?");
            return false;
        }

        final float pos;
        if (mIsVertical) {
            pos = MotionEventCompat.getY(ev, index);
        } else {
            pos = MotionEventCompat.getX(ev, index);
        }

        if (mDataChanged) {
            // Re-sync everything if data has been changed
            // since the scroll operation can query the adapter.
            layoutChildren();
        }

        final float diff = pos - mLastTouchPos + mTouchRemainderPos;
        final int delta = (int) diff;
        mTouchRemainderPos = diff - delta;

        switch (mTouchMode) {
        case TOUCH_MODE_DOWN:
        case TOUCH_MODE_TAP:
        case TOUCH_MODE_DONE_WAITING:
            // Check if we have moved far enough that it looks more like a
            // scroll than a tap
            maybeStartScrolling(delta);
            break;

        case TOUCH_MODE_DRAGGING:
        case TOUCH_MODE_OVERSCROLL:
            mLastTouchPos = pos;
            maybeScroll(delta);
            break;
        }

        break;
    }

    case MotionEvent.ACTION_CANCEL:
        cancelCheckForTap();
        mTouchMode = TOUCH_MODE_REST;
        reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);

        setPressed(false);
        View motionView = this.getChildAt(mMotionPosition - mFirstPosition);
        if (motionView != null) {
            motionView.setPressed(false);
        }

        if (mStartEdge != null && mEndEdge != null) {
            needsInvalidate = mStartEdge.onRelease() | mEndEdge.onRelease();
        }

        recycleVelocityTracker();

        break;

    case MotionEvent.ACTION_UP: {
        switch (mTouchMode) {
        case TOUCH_MODE_DOWN:
        case TOUCH_MODE_TAP:
        case TOUCH_MODE_DONE_WAITING: {
            final int motionPosition = mMotionPosition;
            final View child = getChildAt(motionPosition - mFirstPosition);

            final float x = ev.getX();
            final float y = ev.getY();

            final boolean inList;
            if (mIsVertical) {
                inList = x > getPaddingLeft() && x < getWidth() - getPaddingRight();
            } else {
                inList = y > getPaddingTop() && y < getHeight() - getPaddingBottom();
            }

            if (child != null && !child.hasFocusable() && inList) {
                if (mTouchMode != TOUCH_MODE_DOWN) {
                    child.setPressed(false);
                }

                if (mPerformClick == null) {
                    mPerformClick = new PerformClick();
                }

                final PerformClick performClick = mPerformClick;
                performClick.mClickMotionPosition = motionPosition;
                performClick.rememberWindowAttachCount();

                mResurrectToPosition = motionPosition;

                if (mTouchMode == TOUCH_MODE_DOWN || mTouchMode == TOUCH_MODE_TAP) {
                    if (mTouchMode == TOUCH_MODE_DOWN) {
                        cancelCheckForTap();
                    } else {
                        cancelCheckForLongPress();
                    }

                    mLayoutMode = LAYOUT_NORMAL;

                    if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
                        mTouchMode = TOUCH_MODE_TAP;

                        setPressed(true);
                        positionSelector(mMotionPosition, child);
                        child.setPressed(true);

                        if (mSelector != null) {
                            Drawable d = mSelector.getCurrent();
                            if (d != null && d instanceof TransitionDrawable) {
                                ((TransitionDrawable) d).resetTransition();
                            }
                        }

                        if (mTouchModeReset != null) {
                            removeCallbacks(mTouchModeReset);
                        }

                        mTouchModeReset = new Runnable() {
                            @Override
                            public void run() {
                                mTouchMode = TOUCH_MODE_REST;

                                setPressed(false);
                                child.setPressed(false);

                                if (!mDataChanged) {
                                    performClick.run();
                                }

                                mTouchModeReset = null;
                            }
                        };

                        postDelayed(mTouchModeReset, ViewConfiguration.getPressedStateDuration());
                    } else {
                        mTouchMode = TOUCH_MODE_REST;
                        updateSelectorState();
                    }
                } else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
                    performClick.run();
                }
            }

            mTouchMode = TOUCH_MODE_REST;
            updateSelectorState();

            break;
        }

        case TOUCH_MODE_DRAGGING:
            if (contentFits()) {
                mTouchMode = TOUCH_MODE_REST;
                reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                break;
            }

            mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);

            final float velocity;
            if (mIsVertical) {
                velocity = VelocityTrackerCompat.getYVelocity(mVelocityTracker, mActivePointerId);
            } else {
                velocity = VelocityTrackerCompat.getXVelocity(mVelocityTracker, mActivePointerId);
            }

            if (Math.abs(velocity) >= mFlingVelocity) {
                mTouchMode = TOUCH_MODE_FLINGING;
                reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);

                mScroller.fling(0, 0, (int) (mIsVertical ? 0 : velocity), (int) (mIsVertical ? velocity : 0),
                        (mIsVertical ? 0 : Integer.MIN_VALUE), (mIsVertical ? 0 : Integer.MAX_VALUE),
                        (mIsVertical ? Integer.MIN_VALUE : 0), (mIsVertical ? Integer.MAX_VALUE : 0));

                mLastTouchPos = 0;
                needsInvalidate = true;
            } else {
                mTouchMode = TOUCH_MODE_REST;
                reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
            }

            break;

        case TOUCH_MODE_OVERSCROLL:
            mTouchMode = TOUCH_MODE_REST;
            reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
            break;
        }

        cancelCheckForTap();
        cancelCheckForLongPress();
        setPressed(false);

        if (mStartEdge != null && mEndEdge != null) {
            needsInvalidate |= mStartEdge.onRelease() | mEndEdge.onRelease();
        }

        recycleVelocityTracker();

        break;
    }
    }

    if (needsInvalidate) {
        ViewCompat.postInvalidateOnAnimation(this);
    }

    return true;
}