Example usage for android.view View hasFocus

List of usage examples for android.view View hasFocus

Introduction

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

Prototype

@ViewDebug.ExportedProperty(category = "focus")
public boolean hasFocus() 

Source Link

Document

Returns true if this view has focus itself, or is the ancestor of the view that has focus.

Usage

From source file:io.github.clendy.leanback.widget.GridLayoutManager.java

@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
    if (DEBUG) {//from   w w  w  .  j  ava 2  s .  c  o  m
        Log.v(getTag(),
                "layoutChildren start numRows " + mNumRows + " mScrollOffsetSecondary " + mScrollOffsetSecondary
                        + " mScrollOffsetPrimary " + mScrollOffsetPrimary + " inPreLayout "
                        + state.isPreLayout() + " didStructureChange " + state.didStructureChange()
                        + " mForceFullLayout " + mForceFullLayout);
        Log.v(getTag(), "width " + getWidth() + " height " + getHeight());
    }

    if (mNumRows == 0) {
        // haven't done measure yet
        return;
    }
    final int itemCount = state.getItemCount();
    if (itemCount < 0) {
        return;
    }

    if (!mLayoutEnabled) {
        discardLayoutInfo();
        removeAndRecycleAllViews(recycler);
        return;
    }
    mInLayout = true;

    if (state.didStructureChange()) {
        // didStructureChange() == true means attached item has been removed/added.
        // scroll animation: we are unable to continue a scroll animation,
        //    kill the scroll animation,  and let ItemAnimation move the item to new position.
        // position smooth scroller: kill the animation and stop at final position.
        // pending smooth scroller: stop and scroll to current focus position.
        mBaseGridView.stopScroll();
    }
    final boolean scrollToFocus = !isSmoothScrolling()
            && mFocusScrollStrategy == BaseGridView.FOCUS_SCROLL_ALIGNED;
    if (mFocusPosition != NO_POSITION && mFocusPositionOffset != Integer.MIN_VALUE) {
        mFocusPosition = mFocusPosition + mFocusPositionOffset;
        mSubFocusPosition = 0;
    }
    mFocusPositionOffset = 0;
    saveContext(recycler, state);

    // Track the old focus view so we can adjust our system scroll position
    // so that any scroll animations happening now will remain valid.
    // We must use same delta in Pre Layout (if prelayout exists) and second layout.
    // So we cache the deltas in PreLayout and use it in second layout.
    int delta = 0, deltaSecondary = 0;
    if (mFocusPosition != NO_POSITION && scrollToFocus
            && mBaseGridView.getScrollState() != RecyclerView.SCROLL_STATE_IDLE) {
        // FIXME: we should get the remaining scroll animation offset from RecyclerView
        View focusView = findViewByPosition(mFocusPosition);
        if (focusView != null) {
            if (getScrollPosition(focusView, focusView.findFocus(), sTwoInts)) {
                delta = sTwoInts[0];
                deltaSecondary = sTwoInts[1];
            }
        }
    }

    boolean hadFocus = mBaseGridView.hasFocus();
    int savedFocusPos = mFocusPosition;
    if (mInFastRelayout = layoutInit()) {
        fastRelayout();
        // appends items till focus position.
        if (mFocusPosition != NO_POSITION) {
            View focusView = findViewByPosition(mFocusPosition);
            if (focusView != null) {
                if (scrollToFocus) {
                    scrollToView(focusView, false);
                }
                if (hadFocus && !focusView.hasFocus()) {
                    focusView.requestFocus();
                }
            }
        }
    } else {
        mInLayoutSearchFocus = hadFocus;
        if (mFocusPosition != NO_POSITION) {
            // appends items till focus position.
            while (appendOneColumnVisibleItems() && findViewByPosition(mFocusPosition) == null)
                ;
        }
        // multiple rounds: scrollToView of first round may drag first/last child into
        // "visible window" and we update scrollMin/scrollMax then run second scrollToView
        int oldFirstVisible;
        int oldLastVisible;
        do {
            updateScrollMin();
            updateScrollMax();
            oldFirstVisible = mGrid.getFirstVisibleIndex();
            oldLastVisible = mGrid.getLastVisibleIndex();
            View focusView = findViewByPosition(mFocusPosition);
            // we need force to initialize the child view's position
            scrollToView(focusView, false);
            if (focusView != null && hadFocus && !focusView.hasFocus()) {
                focusView.requestFocus();
            }
            appendVisibleItems();
            prependVisibleItems();
            removeInvisibleViewsAtFront();
            removeInvisibleViewsAtEnd();
        } while (mGrid.getFirstVisibleIndex() != oldFirstVisible
                || mGrid.getLastVisibleIndex() != oldLastVisible);
    }

    if (scrollToFocus) {
        scrollDirectionPrimary(-delta);
        scrollDirectionSecondary(-deltaSecondary);
    }
    appendVisibleItems();
    prependVisibleItems();
    removeInvisibleViewsAtFront();
    removeInvisibleViewsAtEnd();

    if (DEBUG) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        mGrid.debugPrint(pw);
        Log.d(getTag(), sw.toString());
    }

    if (mRowSecondarySizeRefresh) {
        mRowSecondarySizeRefresh = false;
    } else {
        updateRowSecondarySizeRefresh();
    }

    // For fastRelayout, only dispatch event when focus position changes.
    if (mInFastRelayout && mFocusPosition != savedFocusPos) {
        dispatchChildSelected();
    } else if (!mInFastRelayout && mInLayoutSearchFocus) {
        // For full layout we dispatchChildSelected() in createItem() unless searched all
        // children and found none is focusable then dispatchChildSelected() here.
        dispatchChildSelected();
    }

    mInLayout = false;
    leaveContext();
    if (DEBUG)
        Log.v(getTag(), "layoutChildren end");
}

From source file:org.bangbang.support.v4.widget.HListView.java

/**
     * Handle an arrow scroll going up or down.  Take into account whether items are selectable,
     * whether there are focusable items etc.
     *//from w ww  .  jav a  2  s.c  o m
     * @param direction Either {@link android.view.View#FOCUS_UP} or {@link android.view.View#FOCUS_DOWN}.
     * @return Whether any scrolling, selection or focus change occured.
     */
    private boolean arrowScrollImpl(int direction) {
        if (getChildCount() <= 0) {
            return false;
        }

        View selectedView = getSelectedView();

        int nextSelectedPosition = lookForSelectablePositionOnScreen(direction);
        int amountToScroll = amountToScroll(direction, nextSelectedPosition);

        // if we are moving focus, we may OVERRIDE the default behavior
        final ArrowScrollFocusResult focusResult = mItemsCanFocus ? arrowScrollFocused(direction) : null;
        if (focusResult != null) {
            nextSelectedPosition = focusResult.getSelectedPosition();
            amountToScroll = focusResult.getAmountToScroll();
        }

        boolean needToRedraw = focusResult != null;
        if (nextSelectedPosition != INVALID_POSITION) {
            handleNewSelectionChange(selectedView, direction, nextSelectedPosition, focusResult != null);
            setSelectedPositionInt(nextSelectedPosition);
            setNextSelectedPositionInt(nextSelectedPosition);
            selectedView = getSelectedView();
            if (mItemsCanFocus && focusResult == null) {
                // there was no new view found to take focus, make sure we
                // don't leave focus with the old selection
                final View focused = getFocusedChild();
                if (focused != null) {
                    focused.clearFocus();
                }
            }
            needToRedraw = true;
            checkSelectionChanged();
        }

        if (amountToScroll > 0) {
            scrollListItemsBy((direction == View.FOCUS_LEFT) ? amountToScroll : -amountToScroll);
            needToRedraw = true;
        }

        // if we didn't find a new focusable, make sure any existing focused
        // item that was panned off screen gives up focus.
        if (mItemsCanFocus && (focusResult == null) && selectedView != null && selectedView.hasFocus()) {
            final View focused = selectedView.findFocus();
            if (distanceToView(focused) > 0) {
                focused.clearFocus();
            }
        }

        // if  the current selection is panned off, we need to remove the selection
        if (nextSelectedPosition == INVALID_POSITION && selectedView != null
                && !isViewAncestorOf(selectedView, this)) {
            selectedView = null;
            hideSelector();

            // but we don't want to set the ressurect position (that would make subsequent
            // unhandled key events bring back the item we just scrolled off!)
            mResurrectToPosition = INVALID_POSITION;
        }

        if (needToRedraw) {
            if (selectedView != null) {
                positionSelector(selectedView);
                mSelectedTop = selectedView.getTop();
            }
            invalidate();
            invokeOnItemScrollListener();
            return true;
        }

        return false;
    }

From source file:com.awrtechnologies.carbudgetsales.hlistview.widget.HListView.java

/**
 * Handle an arrow scroll going up or down. Take into account whether items are selectable, whether there are focusable items
 * etc./* w w  w . java2  s  .  c o m*/
 * 
 * @param direction
 *           Either {@link android.view.View#FOCUS_UP} or {@link android.view.View#FOCUS_DOWN}.
 * @return Whether any scrolling, selection or focus change occured.
 */
private boolean arrowScrollImpl(int direction) {
    if (getChildCount() <= 0) {
        return false;
    }

    View selectedView = getSelectedView();
    int selectedPos = mSelectedPosition;

    int nextSelectedPosition = lookForSelectablePositionOnScreen(direction);
    int amountToScroll = amountToScroll(direction, nextSelectedPosition);

    // if we are moving focus, we may OVERRIDE the default behavior
    final ArrowScrollFocusResult focusResult = mItemsCanFocus ? arrowScrollFocused(direction) : null;
    if (focusResult != null) {
        nextSelectedPosition = focusResult.getSelectedPosition();
        amountToScroll = focusResult.getAmountToScroll();
    }

    boolean needToRedraw = focusResult != null;
    if (nextSelectedPosition != INVALID_POSITION) {
        handleNewSelectionChange(selectedView, direction, nextSelectedPosition, focusResult != null);
        setSelectedPositionInt(nextSelectedPosition);
        setNextSelectedPositionInt(nextSelectedPosition);
        selectedView = getSelectedView();
        selectedPos = nextSelectedPosition;
        if (mItemsCanFocus && focusResult == null) {
            // there was no new view found to take focus, make sure we
            // don't leave focus with the old selection
            final View focused = getFocusedChild();
            if (focused != null) {
                focused.clearFocus();
            }
        }
        needToRedraw = true;
        checkSelectionChanged();
    }

    if (amountToScroll > 0) {
        scrollListItemsBy((direction == View.FOCUS_UP) ? amountToScroll : -amountToScroll);
        needToRedraw = true;
    }

    // if we didn't find a new focusable, make sure any existing focused
    // item that was panned off screen gives up focus.
    if (mItemsCanFocus && (focusResult == null) && selectedView != null && selectedView.hasFocus()) {
        final View focused = selectedView.findFocus();
        if (!isViewAncestorOf(focused, this) || distanceToView(focused) > 0) {
            focused.clearFocus();
        }
    }

    // if the current selection is panned off, we need to remove the selection
    if (nextSelectedPosition == INVALID_POSITION && selectedView != null
            && !isViewAncestorOf(selectedView, this)) {
        selectedView = null;
        hideSelector();

        // but we don't want to set the ressurect position (that would make subsequent
        // unhandled key events bring back the item we just scrolled off!)
        mResurrectToPosition = INVALID_POSITION;
    }

    if (needToRedraw) {
        if (selectedView != null) {
            positionSelector(selectedPos, selectedView);
            mSelectedLeft = selectedView.getLeft();
        }
        if (!awakenScrollBars()) {
            invalidate();
        }
        invokeOnItemScrollListener();
        return true;
    }

    return false;
}

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

/**
 * Handle an arrow scroll going up or down.  Take into account whether items are selectable,
 * whether there are focusable items etc.
 *
 * @param direction Either {@link android.view.View#FOCUS_UP} or {@link android.view.View#FOCUS_DOWN}.
 * @return Whether any scrolling, selection or focus change occured.
 *//*from   w ww. ja  v  a 2s. c  om*/
private boolean arrowScrollImpl(int direction) {
    if (getChildCount() <= 0) {
        return false;
    }

    View selectedView = getSelectedView();
    int selectedPos = mSelectedPosition;

    int nextSelectedPosition = (direction == View.FOCUS_DOWN) ? lookForSelectablePosition(selectedPos + 1, true)
            : lookForSelectablePosition(selectedPos - 1, false);
    int amountToScroll = amountToScroll(direction, nextSelectedPosition);

    // if we are moving focus, we may OVERRIDE the default behavior
    final ArrowScrollFocusResult focusResult = mItemsCanFocus ? arrowScrollFocused(direction) : null;
    if (focusResult != null) {
        nextSelectedPosition = focusResult.getSelectedPosition();
        amountToScroll = focusResult.getAmountToScroll();
    }

    boolean needToRedraw = focusResult != null;
    if (nextSelectedPosition != INVALID_POSITION) {
        handleNewSelectionChange(selectedView, direction, nextSelectedPosition, focusResult != null);
        setSelectedPositionInt(nextSelectedPosition);
        setNextSelectedPositionInt(nextSelectedPosition);
        selectedView = getSelectedView();
        selectedPos = nextSelectedPosition;
        if (mItemsCanFocus && focusResult == null) {
            // there was no new view found to take focus, make sure we
            // don't leave focus with the old selection
            final View focused = getFocusedChild();
            if (focused != null) {
                focused.clearFocus();
            }
        }
        needToRedraw = true;
        checkSelectionChanged();
    }

    if (amountToScroll > 0) {
        scrollListItemsBy((direction == View.FOCUS_UP) ? amountToScroll : -amountToScroll);
        needToRedraw = true;
    }

    // if we didn't find a new focusable, make sure any existing focused
    // item that was panned off screen gives up focus.
    if (mItemsCanFocus && (focusResult == null) && selectedView != null && selectedView.hasFocus()) {
        final View focused = selectedView.findFocus();
        if (!isViewAncestorOf(focused, this) || distanceToView(focused) > 0) {
            focused.clearFocus();
        }
    }

    // if  the current selection is panned off, we need to remove the selection
    if (nextSelectedPosition == INVALID_POSITION && selectedView != null
            && !isViewAncestorOf(selectedView, this)) {
        selectedView = null;
        hideSelector();

        // but we don't want to set the ressurect position (that would make subsequent
        // unhandled key events bring back the item we just scrolled off!)
        mResurrectToPosition = INVALID_POSITION;
    }

    if (needToRedraw) {
        if (selectedView != null) {
            positionSelector(selectedPos, selectedView);
            mSelectedTop = selectedView.getTop();
        }
        if (!awakenScrollBars()) {
            invalidate();
        }
        invokeOnItemScrollListener();
        return true;
    }

    return false;
}

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

/**
 * Handle an arrow scroll going up or down.  Take into account whether items are selectable,
 * whether there are focusable items etc.
 *
 * @param direction Either {@link android.view.View#FOCUS_LEFT} or {@link android.view.View#FOCUS_RIGHT}.
 * @return Whether any scrolling, selection or focus change occured.
 *///w w  w . j  a  v  a 2 s.c  o  m
private boolean arrowScrollImpl(int direction) {
    if (getChildCount() <= 0) {
        return false;
    }

    View selectedView = getSelectedView();
    int selectedPos = mSelectedPosition;

    int nextSelectedPosition = (direction == View.FOCUS_RIGHT)
            ? lookForSelectablePosition(selectedPos + 1, true)
            : lookForSelectablePosition(selectedPos - 1, false);
    int amountToScroll = amountToScroll(direction, nextSelectedPosition);

    // if we are moving focus, we may OVERRIDE the default behavior
    final ArrowScrollFocusResult focusResult = mItemsCanFocus ? arrowScrollFocused(direction) : null;
    if (focusResult != null) {
        nextSelectedPosition = focusResult.getSelectedPosition();
        amountToScroll = focusResult.getAmountToScroll();
    }

    boolean needToRedraw = focusResult != null;
    if (nextSelectedPosition != INVALID_POSITION) {
        handleNewSelectionChange(selectedView, direction, nextSelectedPosition, focusResult != null);
        setSelectedPositionInt(nextSelectedPosition);
        setNextSelectedPositionInt(nextSelectedPosition);
        selectedView = getSelectedView();
        selectedPos = nextSelectedPosition;
        if (mItemsCanFocus && focusResult == null) {
            // there was no new view found to take focus, make sure we
            // don't leave focus with the old selection
            final View focused = getFocusedChild();
            if (focused != null) {
                focused.clearFocus();
            }
        }
        needToRedraw = true;
        checkSelectionChanged();
    }

    if (amountToScroll > 0) {
        scrollListItemsBy((direction == View.FOCUS_UP) ? amountToScroll : -amountToScroll);
        needToRedraw = true;
    }

    // if we didn't find a new focusable, make sure any existing focused
    // item that was panned off screen gives up focus.
    if (mItemsCanFocus && (focusResult == null) && selectedView != null && selectedView.hasFocus()) {
        final View focused = selectedView.findFocus();
        if (!isViewAncestorOf(focused, this) || distanceToView(focused) > 0) {
            focused.clearFocus();
        }
    }

    // if  the current selection is panned off, we need to remove the selection
    if (nextSelectedPosition == INVALID_POSITION && selectedView != null
            && !isViewAncestorOf(selectedView, this)) {
        selectedView = null;
        hideSelector();

        // but we don't want to set the ressurect position (that would make subsequent
        // unhandled key events bring back the item we just scrolled off!)
        mResurrectToPosition = INVALID_POSITION;
    }

    if (needToRedraw) {
        if (selectedView != null) {
            positionSelector(selectedPos, selectedView);
            mSelectedLeft = selectedView.getLeft();
        }
        if (!awakenScrollBars()) {
            invalidate();
        }
        invokeOnItemScrollListener();
        return true;
    }

    return false;
}

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

/**
 * To avoid horizontal/vertical focus searches changing the selected item,
 * we manually focus search within the selected item (as applicable), and
 * prevent focus from jumping to something within another item.
 *
 * @param direction either {@link View#FOCUS_UP} or {@link View#FOCUS_DOWN} or
 *        {@link View#FOCUS_LEFT} or {@link View#FOCUS_RIGHT} depending on the
 *        current view orientation.//from   www . j  a va2 s .c  o  m
 *
 * @return Whether this consumes the key event.
 */
private boolean handleFocusWithinItem(int direction) {
    forceValidInnerFocusDirection(direction);

    final int numChildren = getChildCount();

    if (mItemsCanFocus && numChildren > 0 && mSelectedPosition != INVALID_POSITION) {
        final View selectedView = getSelectedView();

        if (selectedView != null && selectedView.hasFocus() && selectedView instanceof ViewGroup) {

            final View currentFocus = selectedView.findFocus();
            final View nextFocus = FocusFinder.getInstance().findNextFocus((ViewGroup) selectedView,
                    currentFocus, direction);

            if (nextFocus != null) {
                // Do the math to get interesting rect in next focus' coordinates
                currentFocus.getFocusedRect(mTempRect);
                offsetDescendantRectToMyCoords(currentFocus, mTempRect);
                offsetRectIntoDescendantCoords(nextFocus, mTempRect);

                if (nextFocus.requestFocus(direction, mTempRect)) {
                    return true;
                }
            }

            // We are blocking the key from being handled (by returning true)
            // if the global result is going to be some other view within this
            // list. This is to achieve the overall goal of having horizontal/vertical
            // d-pad navigation remain in the current item depending on the current
            // orientation in this view.
            final View globalNextFocus = FocusFinder.getInstance().findNextFocus((ViewGroup) getRootView(),
                    currentFocus, direction);

            if (globalNextFocus != null) {
                return isViewAncestorOf(globalNextFocus, this);
            }
        }
    }

    return false;
}

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

/**
 * Do an arrow scroll based on focus searching.  If a new view is
 * given focus, return the selection delta and amount to scroll via
 * an {@link ArrowScrollFocusResult}, otherwise, return null.
 *
 * @param direction either {@link android.view.View#FOCUS_UP} or {@link android.view.View#FOCUS_DOWN} or
 *        {@link android.view.View#FOCUS_LEFT} or {@link android.view.View#FOCUS_RIGHT} depending on the
 *        current view orientation.//from   w  w  w.  j a  va  2 s  .c o  m
 *
 * @return The result if focus has changed, or <code>null</code>.
 */
private ArrowScrollFocusResult arrowScrollFocused(final int direction) {
    forceValidFocusDirection(direction);

    final View selectedView = getSelectedView();
    final View newFocus;
    final int searchPoint;

    if (selectedView != null && selectedView.hasFocus()) {
        View oldFocus = selectedView.findFocus();
        newFocus = FocusFinder.getInstance().findNextFocus(this, oldFocus, direction);
    } else {
        if (direction == View.FOCUS_DOWN || direction == View.FOCUS_RIGHT) {
            final int start = getStartEdge();

            final int selectedStart;
            if (selectedView != null) {
                selectedStart = (mIsVertical ? selectedView.getTop() : selectedView.getLeft());
            } else {
                selectedStart = start;
            }

            searchPoint = Math.max(selectedStart, start);
        } else {
            final int end = getEndEdge();

            final int selectedEnd;
            if (selectedView != null) {
                selectedEnd = getChildEndEdge(selectedView);
            } else {
                selectedEnd = end;
            }

            searchPoint = Math.min(selectedEnd, end);
        }

        final int x = (mIsVertical ? 0 : searchPoint);
        final int y = (mIsVertical ? searchPoint : 0);
        mTempRect.set(x, y, x, y);

        newFocus = FocusFinder.getInstance().findNextFocusFromRect(this, mTempRect, direction);
    }

    if (newFocus != null) {
        final int positionOfNewFocus = positionOfNewFocus(newFocus);

        // If the focus change is in a different new position, make sure
        // we aren't jumping over another selectable position.
        if (mSelectedPosition != INVALID_POSITION && positionOfNewFocus != mSelectedPosition) {
            final int selectablePosition = lookForSelectablePositionOnScreen(direction);

            final boolean movingForward = (direction == View.FOCUS_DOWN || direction == View.FOCUS_RIGHT);
            final boolean movingBackward = (direction == View.FOCUS_UP || direction == View.FOCUS_LEFT);

            if (selectablePosition != INVALID_POSITION
                    && ((movingForward && selectablePosition < positionOfNewFocus)
                            || (movingBackward && selectablePosition > positionOfNewFocus))) {
                return null;
            }
        }

        int focusScroll = amountToScrollToNewFocus(direction, newFocus, positionOfNewFocus);

        final int maxScrollAmount = getMaxScrollAmount();
        if (focusScroll < maxScrollAmount) {
            // Not moving too far, safe to give next view focus
            newFocus.requestFocus(direction);
            mArrowScrollFocusResult.populate(positionOfNewFocus, focusScroll);
            return mArrowScrollFocusResult;
        } else if (distanceToView(newFocus) < maxScrollAmount) {
            // Case to consider:
            // Too far to get entire next focusable on screen, but by going
            // max scroll amount, we are getting it at least partially in view,
            // so give it focus and scroll the max amount.
            newFocus.requestFocus(direction);
            mArrowScrollFocusResult.populate(positionOfNewFocus, maxScrollAmount);
            return mArrowScrollFocusResult;
        }
    }

    return null;
}

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

/**
 * Do an arrow scroll based on focus searching.  If a new view is
 * given focus, return the selection delta and amount to scroll via
 * an {@link ArrowScrollFocusResult}, otherwise, return null.
 *
 * @param direction either {@link View#FOCUS_UP} or {@link View#FOCUS_DOWN} or
 *        {@link View#FOCUS_LEFT} or {@link View#FOCUS_RIGHT} depending on the
 *        current view orientation./*from   w  w  w .ja v  a  2  s .com*/
 *
 * @return The result if focus has changed, or <code>null</code>.
 */
private ArrowScrollFocusResult arrowScrollFocused(final int direction) {
    forceValidFocusDirection(direction);

    final View selectedView = getSelectedView();
    final View newFocus;
    final int searchPoint;

    if (selectedView != null && selectedView.hasFocus()) {
        View oldFocus = selectedView.findFocus();
        newFocus = FocusFinder.getInstance().findNextFocus(this, oldFocus, direction);
    } else {
        if (direction == View.FOCUS_DOWN || direction == View.FOCUS_RIGHT) {
            final int start = (mIsVertical ? getPaddingTop() : getPaddingLeft());

            final int selectedStart;
            if (selectedView != null) {
                selectedStart = (mIsVertical ? selectedView.getTop() : selectedView.getLeft());
            } else {
                selectedStart = start;
            }

            searchPoint = Math.max(selectedStart, start);
        } else {
            final int end = (mIsVertical ? getHeight() - getPaddingBottom() : getWidth() - getPaddingRight());

            final int selectedEnd;
            if (selectedView != null) {
                selectedEnd = (mIsVertical ? selectedView.getBottom() : selectedView.getRight());
            } else {
                selectedEnd = end;
            }

            searchPoint = Math.min(selectedEnd, end);
        }

        final int x = (mIsVertical ? 0 : searchPoint);
        final int y = (mIsVertical ? searchPoint : 0);
        mTempRect.set(x, y, x, y);

        newFocus = FocusFinder.getInstance().findNextFocusFromRect(this, mTempRect, direction);
    }

    if (newFocus != null) {
        final int positionOfNewFocus = positionOfNewFocus(newFocus);

        // If the focus change is in a different new position, make sure
        // we aren't jumping over another selectable position.
        if (mSelectedPosition != INVALID_POSITION && positionOfNewFocus != mSelectedPosition) {
            final int selectablePosition = lookForSelectablePositionOnScreen(direction);

            final boolean movingForward = (direction == View.FOCUS_DOWN || direction == View.FOCUS_RIGHT);
            final boolean movingBackward = (direction == View.FOCUS_UP || direction == View.FOCUS_LEFT);

            if (selectablePosition != INVALID_POSITION
                    && ((movingForward && selectablePosition < positionOfNewFocus)
                            || (movingBackward && selectablePosition > positionOfNewFocus))) {
                return null;
            }
        }

        int focusScroll = amountToScrollToNewFocus(direction, newFocus, positionOfNewFocus);

        final int maxScrollAmount = getMaxScrollAmount();
        if (focusScroll < maxScrollAmount) {
            // Not moving too far, safe to give next view focus
            newFocus.requestFocus(direction);
            mArrowScrollFocusResult.populate(positionOfNewFocus, focusScroll);
            return mArrowScrollFocusResult;
        } else if (distanceToView(newFocus) < maxScrollAmount) {
            // Case to consider:
            // Too far to get entire next focusable on screen, but by going
            // max scroll amount, we are getting it at least partially in view,
            // so give it focus and scroll the max amount.
            newFocus.requestFocus(direction);
            mArrowScrollFocusResult.populate(positionOfNewFocus, maxScrollAmount);
            return mArrowScrollFocusResult;
        }
    }

    return null;
}

From source file:com.artifex.mupdf.view.ThumbnailViews.java

/**
 * To avoid horizontal/vertical focus searches changing the selected item,
 * we manually focus search within the selected item (as applicable), and
 * prevent focus from jumping to something within another item.
 * //from   ww  w  .  j a  v a  2 s. co m
 * @param direction
 *            either {@link View#FOCUS_UP} or {@link View#FOCUS_DOWN} or
 *            {@link View#FOCUS_LEFT} or {@link View#FOCUS_RIGHT} depending
 *            on the current view orientation.
 * 
 * @return Whether this consumes the key event.
 */
private boolean handleFocusWithinItem(int direction) {
    forceValidInnerFocusDirection(direction);

    final int numChildren = getChildCount();

    if (mItemsCanFocus && numChildren > 0 && mSelectedPosition != INVALID_POSITION) {
        final View selectedView = getSelectedView();

        if (selectedView != null && selectedView.hasFocus() && selectedView instanceof ViewGroup) {

            final View currentFocus = selectedView.findFocus();
            final View nextFocus = FocusFinder.getInstance().findNextFocus((ViewGroup) selectedView,
                    currentFocus, direction);

            if (nextFocus != null) {
                // Do the math to get interesting rect in next focus'
                // coordinates
                currentFocus.getFocusedRect(mTempRect);
                offsetDescendantRectToMyCoords(currentFocus, mTempRect);
                offsetRectIntoDescendantCoords(nextFocus, mTempRect);

                if (nextFocus.requestFocus(direction, mTempRect)) {
                    return true;
                }
            }

            // We are blocking the key from being handled (by returning
            // true)
            // if the global result is going to be some other view within
            // this
            // list. This is to achieve the overall goal of having
            // horizontal/vertical
            // d-pad navigation remain in the current item depending on the
            // current
            // orientation in this view.
            final View globalNextFocus = FocusFinder.getInstance().findNextFocus((ViewGroup) getRootView(),
                    currentFocus, direction);

            if (globalNextFocus != null) {
                return isViewAncestorOf(globalNextFocus, this);
            }
        }
    }

    return false;
}

From source file:com.artifex.mupdf.view.ThumbnailViews.java

/**
 * Do an arrow scroll based on focus searching. If a new view is given
 * focus, return the selection delta and amount to scroll via an
 * {@link ArrowScrollFocusResult}, otherwise, return null.
 * /*from w  ww.java  2  s  .  c  o m*/
 * @param direction
 *            either {@link View#FOCUS_UP} or {@link View#FOCUS_DOWN} or
 *            {@link View#FOCUS_LEFT} or {@link View#FOCUS_RIGHT} depending
 *            on the current view orientation.
 * 
 * @return The result if focus has changed, or <code>null</code>.
 */
private ArrowScrollFocusResult arrowScrollFocused(final int direction) {
    forceValidFocusDirection(direction);

    final View selectedView = getSelectedView();
    final View newFocus;
    final int searchPoint;

    if (selectedView != null && selectedView.hasFocus()) {
        View oldFocus = selectedView.findFocus();
        newFocus = FocusFinder.getInstance().findNextFocus(this, oldFocus, direction);
    } else {
        if (direction == View.FOCUS_DOWN || direction == View.FOCUS_RIGHT) {
            final int start = (mIsVertical ? getPaddingTop() : getPaddingLeft());

            final int selectedStart;
            if (selectedView != null) {
                selectedStart = (mIsVertical ? selectedView.getTop() : selectedView.getLeft());
            } else {
                selectedStart = start;
            }

            searchPoint = Math.max(selectedStart, start);
        } else {
            final int end = (mIsVertical ? getHeight() - getPaddingBottom() : getWidth() - getPaddingRight());

            final int selectedEnd;
            if (selectedView != null) {
                selectedEnd = (mIsVertical ? selectedView.getBottom() : selectedView.getRight());
            } else {
                selectedEnd = end;
            }

            searchPoint = Math.min(selectedEnd, end);
        }

        final int x = (mIsVertical ? 0 : searchPoint);
        final int y = (mIsVertical ? searchPoint : 0);
        mTempRect.set(x, y, x, y);

        newFocus = FocusFinder.getInstance().findNextFocusFromRect(this, mTempRect, direction);
    }

    if (newFocus != null) {
        final int positionOfNewFocus = positionOfNewFocus(newFocus);

        // If the focus change is in a different new position, make sure
        // we aren't jumping over another selectable position.
        if (mSelectedPosition != INVALID_POSITION && positionOfNewFocus != mSelectedPosition) {
            final int selectablePosition = lookForSelectablePositionOnScreen(direction);

            final boolean movingForward = (direction == View.FOCUS_DOWN || direction == View.FOCUS_RIGHT);
            final boolean movingBackward = (direction == View.FOCUS_UP || direction == View.FOCUS_LEFT);

            if (selectablePosition != INVALID_POSITION
                    && ((movingForward && selectablePosition < positionOfNewFocus)
                            || (movingBackward && selectablePosition > positionOfNewFocus))) {
                return null;
            }
        }

        int focusScroll = amountToScrollToNewFocus(direction, newFocus, positionOfNewFocus);

        final int maxScrollAmount = getMaxScrollAmount();
        if (focusScroll < maxScrollAmount) {
            // Not moving too far, safe to give next view focus
            newFocus.requestFocus(direction);
            mArrowScrollFocusResult.populate(positionOfNewFocus, focusScroll);
            return mArrowScrollFocusResult;
        } else if (distanceToView(newFocus) < maxScrollAmount) {
            // Case to consider:
            // Too far to get entire next focusable on screen, but by going
            // max scroll amount, we are getting it at least partially in
            // view,
            // so give it focus and scroll the max amount.
            newFocus.requestFocus(direction);
            mArrowScrollFocusResult.populate(positionOfNewFocus, maxScrollAmount);
            return mArrowScrollFocusResult;
        }
    }

    return null;
}