Example usage for android.view View FOCUS_DOWN

List of usage examples for android.view View FOCUS_DOWN

Introduction

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

Prototype

int FOCUS_DOWN

To view the source code for android.view View FOCUS_DOWN.

Click Source Link

Document

Use with #focusSearch(int) .

Usage

From source file:VerticalViewPager.java

public boolean arrowScroll(int direction) {
    View currentFocused = findFocus();
    if (currentFocused == this) {
        currentFocused = null;// w w  w  . j a  v  a  2 s .c  o  m
    } else if (currentFocused != null) {
        boolean isChild = false;
        for (ViewParent parent = currentFocused.getParent(); parent instanceof ViewGroup; parent = parent
                .getParent()) {
            if (parent == this) {
                isChild = true;
                break;
            }
        }
        if (!isChild) {
            // This would cause the focus search down below to fail in fun ways.
            final StringBuilder sb = new StringBuilder();
            sb.append(currentFocused.getClass().getSimpleName());
            for (ViewParent parent = currentFocused.getParent(); parent instanceof ViewGroup; parent = parent
                    .getParent()) {
                sb.append(" => ").append(parent.getClass().getSimpleName());
            }
            Log.e(TAG, "arrowScroll tried to find focus based on non-child " + "current focused view "
                    + sb.toString());
            currentFocused = null;
        }
    }

    boolean handled = false;

    View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, direction);
    if (nextFocused != null && nextFocused != currentFocused) {
        if (direction == View.FOCUS_UP) {
            // If there is nothing up, or this is causing us to
            // jump down, then what we really want to do is page down.
            final int nextUp = getChildRectInPagerCoordinates(mTempRect, nextFocused).top;
            final int currUp = getChildRectInPagerCoordinates(mTempRect, currentFocused).top;

            if (currentFocused != null && nextUp >= currUp) {
                handled = pageUp();
            } else {
                handled = nextFocused.requestFocus();
            }
        } else if (direction == View.FOCUS_DOWN) {
            // If there is nothing to the bottom, or this is causing us to
            // jump up, then what we really want to do is page bottom.
            final int nextDown = getChildRectInPagerCoordinates(mTempRect, nextFocused).bottom;
            final int currDown = getChildRectInPagerCoordinates(mTempRect, currentFocused).bottom;
            if (currentFocused != null && nextDown <= currDown) {
                handled = pageDown();
            } else {
                handled = nextFocused.requestFocus();
            }
        }
    } else if (direction == FOCUS_UP || direction == FOCUS_BACKWARD) {
        // Trying to move left and nothing there; try to page.
        handled = pageUp();
    } else if (direction == FOCUS_DOWN || direction == FOCUS_FORWARD) {
        // Trying to move right and nothing there; try to page.
        handled = pageDown();
    }
    if (handled) {
        playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction));
    }
    return handled;
}

From source file:cn.ismartv.tvrecyclerview.widget.RecyclerView.java

/**
 * Logic taken from FocusSearch#isCandidate
 *//*from w w w .  j av  a2  s.com*/
private boolean isPreferredNextFocusAbsolute(View focused, View next, int direction) {
    mTempRect.set(0, 0, focused.getWidth(), focused.getHeight());
    mTempRect2.set(0, 0, next.getWidth(), next.getHeight());
    offsetDescendantRectToMyCoords(focused, mTempRect);
    offsetDescendantRectToMyCoords(next, mTempRect2);
    switch (direction) {
    case View.FOCUS_LEFT:
        return (mTempRect.right > mTempRect2.right || mTempRect.left >= mTempRect2.right)
                && mTempRect.left > mTempRect2.left;
    case View.FOCUS_RIGHT:
        return (mTempRect.left < mTempRect2.left || mTempRect.right <= mTempRect2.left)
                && mTempRect.right < mTempRect2.right;
    case View.FOCUS_UP:
        return (mTempRect.bottom > mTempRect2.bottom || mTempRect.top >= mTempRect2.bottom)
                && mTempRect.top > mTempRect2.top;
    case View.FOCUS_DOWN:
        return (mTempRect.top < mTempRect2.top || mTempRect.bottom <= mTempRect2.top)
                && mTempRect.bottom < mTempRect2.bottom;
    }
    throw new IllegalArgumentException("direction must be absolute. received:" + direction);
}

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

/**
 * What is the distance between the source and destination rectangles given the direction of
 * focus navigation between them? The direction basically helps figure out more quickly what is
 * self evident by the relationship between the rects...
 *
 * @param source the source rectangle/*from   w w w. j a v a 2s  . com*/
 * @param dest the destination rectangle
 * @param direction the direction
 * @return the distance between the rectangles
 */
private static int getDistance(Rect source, Rect dest, int direction) {
    int sX, sY; // source x, y
    int dX, dY; // dest x, y

    switch (direction) {
    case View.FOCUS_RIGHT:
        sX = source.right;
        sY = source.top + source.height() / 2;
        dX = dest.left;
        dY = dest.top + dest.height() / 2;
        break;

    case View.FOCUS_DOWN:
        sX = source.left + source.width() / 2;
        sY = source.bottom;
        dX = dest.left + dest.width() / 2;
        dY = dest.top;
        break;

    case View.FOCUS_LEFT:
        sX = source.left;
        sY = source.top + source.height() / 2;
        dX = dest.right;
        dY = dest.top + dest.height() / 2;
        break;

    case View.FOCUS_UP:
        sX = source.left + source.width() / 2;
        sY = source.top;
        dX = dest.left + dest.width() / 2;
        dY = dest.bottom;
        break;

    case View.FOCUS_FORWARD:
    case View.FOCUS_BACKWARD:
        sX = source.right + source.width() / 2;
        sY = source.top + source.height() / 2;
        dX = dest.left + dest.width() / 2;
        dY = dest.top + dest.height() / 2;
        break;

    default:
        throw new IllegalArgumentException("direction must be one of "
                + "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT, " + "FOCUS_FORWARD, FOCUS_BACKWARD}.");
    }

    int deltaX = dX - sX;
    int deltaY = dY - sY;

    return deltaY * deltaY + deltaX * deltaX;
}

From source file:com.ferdi2005.secondgram.support.widget.RecyclerView.java

/**
 * Since RecyclerView is a collection ViewGroup that includes virtual children (items that are
 * in the Adapter but not visible in the UI), it employs a more involved focus search strategy
 * that differs from other ViewGroups./*w  w  w. j a  v  a2  s .  c  o  m*/
 * <p>
 * It first does a focus search within the RecyclerView. If this search finds a View that is in
 * the focus direction with respect to the currently focused View, RecyclerView returns that
 * child as the next focus target. When it cannot find such child, it calls
 * {@link LayoutManager#onFocusSearchFailed(View, int, Recycler, State)} to layout more Views
 * in the focus search direction. If LayoutManager adds a View that matches the
 * focus search criteria, it will be returned as the focus search result. Otherwise,
 * RecyclerView will call parent to handle the focus search like a regular ViewGroup.
 * <p>
 * When the direction is {@link View#FOCUS_FORWARD} or {@link View#FOCUS_BACKWARD}, a View that
 * is not in the focus direction is still valid focus target which may not be the desired
 * behavior if the Adapter has more children in the focus direction. To handle this case,
 * RecyclerView converts the focus direction to an absolute direction and makes a preliminary
 * focus search in that direction. If there are no Views to gain focus, it will call
 * {@link LayoutManager#onFocusSearchFailed(View, int, Recycler, State)} before running a
 * focus search with the original (relative) direction. This allows RecyclerView to provide
 * better candidates to the focus search while still allowing the view system to take focus from
 * the RecyclerView and give it to a more suitable child if such child exists.
 *
 * @param focused The view that currently has focus
 * @param direction One of {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN},
 * {@link View#FOCUS_LEFT}, {@link View#FOCUS_RIGHT}, {@link View#FOCUS_FORWARD},
 * {@link View#FOCUS_BACKWARD} or 0 for not applicable.
 *
 * @return A new View that can be the next focus after the focused View
 */
@Override
public View focusSearch(View focused, int direction) {
    View result = mLayout.onInterceptFocusSearch(focused, direction);
    if (result != null) {
        return result;
    }
    final boolean canRunFocusFailure = mAdapter != null && mLayout != null && !isComputingLayout()
            && !mLayoutFrozen;

    final FocusFinder ff = FocusFinder.getInstance();
    if (canRunFocusFailure && (direction == View.FOCUS_FORWARD || direction == View.FOCUS_BACKWARD)) {
        // convert direction to absolute direction and see if we have a view there and if not
        // tell LayoutManager to add if it can.
        boolean needsFocusFailureLayout = false;
        if (mLayout.canScrollVertically()) {
            final int absDir = direction == View.FOCUS_FORWARD ? View.FOCUS_DOWN : View.FOCUS_UP;
            final View found = ff.findNextFocus(this, focused, absDir);
            needsFocusFailureLayout = found == null;
            if (FORCE_ABS_FOCUS_SEARCH_DIRECTION) {
                // Workaround for broken FOCUS_BACKWARD in API 15 and older devices.
                direction = absDir;
            }
        }
        if (!needsFocusFailureLayout && mLayout.canScrollHorizontally()) {
            boolean rtl = mLayout.getLayoutDirection() == ViewCompat.LAYOUT_DIRECTION_RTL;
            final int absDir = (direction == View.FOCUS_FORWARD) ^ rtl ? View.FOCUS_RIGHT : View.FOCUS_LEFT;
            final View found = ff.findNextFocus(this, focused, absDir);
            needsFocusFailureLayout = found == null;
            if (FORCE_ABS_FOCUS_SEARCH_DIRECTION) {
                // Workaround for broken FOCUS_BACKWARD in API 15 and older devices.
                direction = absDir;
            }
        }
        if (needsFocusFailureLayout) {
            consumePendingUpdateOperations();
            final View focusedItemView = findContainingItemView(focused);
            if (focusedItemView == null) {
                // panic, focused view is not a child anymore, cannot call super.
                return null;
            }
            eatRequestLayout();
            mLayout.onFocusSearchFailed(focused, direction, mRecycler, mState);
            resumeRequestLayout(false);
        }
        result = ff.findNextFocus(this, focused, direction);
    } else {
        result = ff.findNextFocus(this, focused, direction);
        if (result == null && canRunFocusFailure) {
            consumePendingUpdateOperations();
            final View focusedItemView = findContainingItemView(focused);
            if (focusedItemView == null) {
                // panic, focused view is not a child anymore, cannot call super.
                return null;
            }
            eatRequestLayout();
            result = mLayout.onFocusSearchFailed(focused, direction, mRecycler, mState);
            resumeRequestLayout(false);
        }
    }
    return isPreferredNextFocus(focused, result, direction) ? result : super.focusSearch(focused, direction);
}

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

/**
 * Determine how much we need to scroll in order to get the next selected view
 * visible, with a fading edge showing below as applicable.  The amount is
 * capped at {@link #getMaxScrollAmount()} .
 *
 * @param direction either {@link android.view.View#FOCUS_UP} or
 *        {@link android.view.View#FOCUS_DOWN}.
 * @param nextSelectedPosition The position of the next selection, or
 *        {@link #INVALID_POSITION} if there is no next selectable position
 * @return The amount to scroll. Note: this is always positive!  Direction
 *         needs to be taken into account when actually scrolling.
 *///  w ww.  j  a  v  a2s .  c o  m
private int amountToScroll(int direction, int nextSelectedPosition) {
    final int listRight = getWidth() - mListPadding.right;
    final int listLeft = mListPadding.left;

    int numChildren = getChildCount();

    if (direction == View.FOCUS_DOWN) {
        int indexToMakeVisible = numChildren - 1;
        if (nextSelectedPosition != INVALID_POSITION) {
            indexToMakeVisible = nextSelectedPosition - mFirstPosition;
        }
        while (numChildren <= indexToMakeVisible) {
            // Child to view is not attached yet.
            addViewToRight(getChildAt(numChildren - 1), mFirstPosition + numChildren - 1);
            numChildren++;
        }
        final int positionToMakeVisible = mFirstPosition + indexToMakeVisible;
        final View viewToMakeVisible = getChildAt(indexToMakeVisible);

        int goalRight = listRight;
        if (positionToMakeVisible < mItemCount - 1) {
            goalRight -= getArrowScrollPreviewLength();
        }

        if (viewToMakeVisible.getRight() <= goalRight) {
            // item is fully visible.
            return 0;
        }

        if (nextSelectedPosition != INVALID_POSITION
                && (goalRight - viewToMakeVisible.getLeft()) >= getMaxScrollAmount()) {
            // item already has enough of it visible, changing selection is good enough
            return 0;
        }

        int amountToScroll = (viewToMakeVisible.getRight() - goalRight);

        if ((mFirstPosition + numChildren) == mItemCount) {
            // last is last in list -> make sure we don't scroll past it
            final int max = getChildAt(numChildren - 1).getRight() - listRight;
            amountToScroll = Math.min(amountToScroll, max);
        }

        return Math.min(amountToScroll, getMaxScrollAmount());
    } else {
        int indexToMakeVisible = 0;
        if (nextSelectedPosition != INVALID_POSITION) {
            indexToMakeVisible = nextSelectedPosition - mFirstPosition;
        }
        while (indexToMakeVisible < 0) {
            // Child to view is not attached yet.
            addViewToLeft(getChildAt(0), mFirstPosition);
            mFirstPosition--;
            indexToMakeVisible = nextSelectedPosition - mFirstPosition;
        }
        final int positionToMakeVisible = mFirstPosition + indexToMakeVisible;
        final View viewToMakeVisible = getChildAt(indexToMakeVisible);
        int goalLeft = listLeft;
        if (positionToMakeVisible > 0) {
            goalLeft += getArrowScrollPreviewLength();
        }
        if (viewToMakeVisible.getLeft() >= goalLeft) {
            // item is fully visible.
            return 0;
        }

        if (nextSelectedPosition != INVALID_POSITION
                && (viewToMakeVisible.getRight() - goalLeft) >= getMaxScrollAmount()) {
            // item already has enough of it visible, changing selection is good enough
            return 0;
        }

        int amountToScroll = (goalLeft - viewToMakeVisible.getLeft());
        if (mFirstPosition == 0) {
            // first is first in list -> make sure we don't scroll past it
            final int max = listLeft - getChildAt(0).getLeft();
            amountToScroll = Math.min(amountToScroll, max);
        }
        return Math.min(amountToScroll, getMaxScrollAmount());
    }
}

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

/**
 * Determine how much we need to scroll in order to get the next selected view
 * visible, with a fading edge showing below as applicable.  The amount is
 * capped at {@link #getMaxScrollAmount()} .
 *
 * @param direction either {@link android.view.View#FOCUS_UP} or
 *        {@link android.view.View#FOCUS_DOWN}.
 * @param nextSelectedPosition The position of the next selection, or
 *        {@link #INVALID_POSITION} if there is no next selectable position
 * @return The amount to scroll. Note: this is always positive!  Direction
 *         needs to be taken into account when actually scrolling.
 */// ww w.  j  a v  a 2  s . c  o m
private int amountToScroll(int direction, int nextSelectedPosition) {
    final int listBottom = getHeight() - mListPadding.bottom;
    final int listTop = mListPadding.top;

    int numChildren = getChildCount();

    if (direction == View.FOCUS_DOWN) {
        int indexToMakeVisible = numChildren - 1;
        if (nextSelectedPosition != INVALID_POSITION) {
            indexToMakeVisible = nextSelectedPosition - mFirstPosition;
        }
        while (numChildren <= indexToMakeVisible) {
            // Child to view is not attached yet.
            addViewBelow(getChildAt(numChildren - 1), mFirstPosition + numChildren - 1);
            numChildren++;
        }
        final int positionToMakeVisible = mFirstPosition + indexToMakeVisible;
        final View viewToMakeVisible = getChildAt(indexToMakeVisible);

        int goalBottom = listBottom;
        if (positionToMakeVisible < mItemCount - 1) {
            goalBottom -= getArrowScrollPreviewLength();
        }

        if (viewToMakeVisible.getBottom() <= goalBottom) {
            // item is fully visible.
            return 0;
        }

        if (nextSelectedPosition != INVALID_POSITION
                && (goalBottom - viewToMakeVisible.getTop()) >= getMaxScrollAmount()) {
            // item already has enough of it visible, changing selection is good enough
            return 0;
        }

        int amountToScroll = (viewToMakeVisible.getBottom() - goalBottom);

        if ((mFirstPosition + numChildren) == mItemCount) {
            // last is last in list -> make sure we don't scroll past it
            final int max = getChildAt(numChildren - 1).getBottom() - listBottom;
            amountToScroll = Math.min(amountToScroll, max);
        }

        return Math.min(amountToScroll, getMaxScrollAmount());
    } else {
        int indexToMakeVisible = 0;
        if (nextSelectedPosition != INVALID_POSITION) {
            indexToMakeVisible = nextSelectedPosition - mFirstPosition;
        }
        while (indexToMakeVisible < 0) {
            // Child to view is not attached yet.
            addViewAbove(getChildAt(0), mFirstPosition);
            mFirstPosition--;
            indexToMakeVisible = nextSelectedPosition - mFirstPosition;
        }
        final int positionToMakeVisible = mFirstPosition + indexToMakeVisible;
        final View viewToMakeVisible = getChildAt(indexToMakeVisible);
        int goalTop = listTop;
        if (positionToMakeVisible > 0) {
            goalTop += getArrowScrollPreviewLength();
        }
        if (viewToMakeVisible.getTop() >= goalTop) {
            // item is fully visible.
            return 0;
        }

        if (nextSelectedPosition != INVALID_POSITION
                && (viewToMakeVisible.getBottom() - goalTop) >= getMaxScrollAmount()) {
            // item already has enough of it visible, changing selection is good enough
            return 0;
        }

        int amountToScroll = (goalTop - viewToMakeVisible.getTop());
        if (mFirstPosition == 0) {
            // first is first in list -> make sure we don't scroll past it
            final int max = listTop - getChildAt(0).getTop();
            amountToScroll = Math.min(amountToScroll, max);
        }
        return Math.min(amountToScroll, getMaxScrollAmount());
    }
}

From source file:eu.kanade.tachiyomi.ui.reader.viewer.pager.vertical.VerticalViewPagerImpl.java

public boolean arrowScroll(int direction) {
    View currentFocused = findFocus();
    if (currentFocused == this) {
        currentFocused = null;/*from   w  w  w.j a  v  a2 s .  co  m*/
    } else if (currentFocused != null) {
        boolean isChild = false;
        for (ViewParent parent = currentFocused.getParent(); parent instanceof ViewGroup; parent = parent
                .getParent()) {
            if (parent == this) {
                isChild = true;
                break;
            }
        }
        if (!isChild) {
            // This would cause the focus search down below to fail in fun ways.
            final StringBuilder sb = new StringBuilder();
            sb.append(currentFocused.getClass().getSimpleName());
            for (ViewParent parent = currentFocused.getParent(); parent instanceof ViewGroup; parent = parent
                    .getParent()) {
                sb.append(" => ").append(parent.getClass().getSimpleName());
            }
            Log.e(TAG, "arrowScroll tried to find focus based on non-child " + "current focused view "
                    + sb.toString());
            currentFocused = null;
        }
    }

    boolean handled = false;

    View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, direction);
    if (nextFocused != null && nextFocused != currentFocused) {
        if (direction == View.FOCUS_UP) {
            // If there is nothing to the left, or this is causing us to
            // jump to the right, then what we really want to do is page left.
            final int nextTop = getChildRectInPagerCoordinates(mTempRect, nextFocused).top;
            final int currTop = getChildRectInPagerCoordinates(mTempRect, currentFocused).top;
            if (currentFocused != null && nextTop >= currTop) {
                handled = pageUp();
            } else {
                handled = nextFocused.requestFocus();
            }
        } else if (direction == View.FOCUS_DOWN) {
            // If there is nothing to the right, or this is causing us to
            // jump to the left, then what we really want to do is page right.
            final int nextDown = getChildRectInPagerCoordinates(mTempRect, nextFocused).bottom;
            final int currDown = getChildRectInPagerCoordinates(mTempRect, currentFocused).bottom;
            if (currentFocused != null && nextDown <= currDown) {
                handled = pageDown();
            } else {
                handled = nextFocused.requestFocus();
            }
        }
    } else if (direction == FOCUS_UP || direction == FOCUS_BACKWARD) {
        // Trying to move left and nothing there; try to page.
        handled = pageUp();
    } else if (direction == FOCUS_DOWN || direction == FOCUS_FORWARD) {
        // Trying to move right and nothing there; try to page.
        handled = pageDown();
    }
    if (handled) {
        playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction));
    }
    return handled;
}

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

/**
 * Determine how much we need to scroll in order to get the next selected view visible, with a fading edge showing below as
 * applicable. The amount is capped at {@link #getMaxScrollAmount()} .
 * /*from  w ww.j a  v  a  2  s. c  om*/
 * @param direction
 *           either {@link android.view.View#FOCUS_UP} or {@link android.view.View#FOCUS_DOWN}.
 * @param nextSelectedPosition
 *           The position of the next selection, or {@link #INVALID_POSITION} if there is no next selectable position
 * @return The amount to scroll. Note: this is always positive! Direction needs to be taken into account when actually scrolling.
 */
private int amountToScroll(int direction, int nextSelectedPosition) {
    final int listRight = getWidth() - mListPadding.right;
    final int listLeft = mListPadding.left;

    final int numChildren = getChildCount();

    if (direction == View.FOCUS_DOWN) {
        int indexToMakeVisible = numChildren - 1;
        if (nextSelectedPosition != INVALID_POSITION) {
            indexToMakeVisible = nextSelectedPosition - mFirstPosition;
        }

        final int positionToMakeVisible = mFirstPosition + indexToMakeVisible;
        final View viewToMakeVisible = getChildAt(indexToMakeVisible);

        int goalRight = listRight;
        if (positionToMakeVisible < mItemCount - 1) {
            goalRight -= getArrowScrollPreviewLength();
        }

        if (viewToMakeVisible.getRight() <= goalRight) {
            // item is fully visible.
            return 0;
        }

        if (nextSelectedPosition != INVALID_POSITION
                && (goalRight - viewToMakeVisible.getLeft()) >= getMaxScrollAmount()) {
            // item already has enough of it visible, changing selection is good enough
            return 0;
        }

        int amountToScroll = (viewToMakeVisible.getRight() - goalRight);

        if ((mFirstPosition + numChildren) == mItemCount) {
            // last is last in list -> make sure we don't scroll past it
            final int max = getChildAt(numChildren - 1).getRight() - listRight;
            amountToScroll = Math.min(amountToScroll, max);
        }

        return Math.min(amountToScroll, getMaxScrollAmount());
    } else {
        int indexToMakeVisible = 0;
        if (nextSelectedPosition != INVALID_POSITION) {
            indexToMakeVisible = nextSelectedPosition - mFirstPosition;
        }
        final int positionToMakeVisible = mFirstPosition + indexToMakeVisible;
        final View viewToMakeVisible = getChildAt(indexToMakeVisible);
        int goalLeft = listLeft;
        if (positionToMakeVisible > 0) {
            goalLeft += getArrowScrollPreviewLength();
        }
        if (viewToMakeVisible.getLeft() >= goalLeft) {
            // item is fully visible.
            return 0;
        }

        if (nextSelectedPosition != INVALID_POSITION
                && (viewToMakeVisible.getRight() - goalLeft) >= getMaxScrollAmount()) {
            // item already has enough of it visible, changing selection is good enough
            return 0;
        }

        int amountToScroll = (goalLeft - viewToMakeVisible.getLeft());
        if (mFirstPosition == 0) {
            // first is first in list -> make sure we don't scroll past it
            final int max = listLeft - getChildAt(0).getLeft();
            amountToScroll = Math.min(amountToScroll, max);
        }
        return Math.min(amountToScroll, getMaxScrollAmount());
    }
}

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

/**
 * @param direction either {@link android.view.View#FOCUS_UP} or
 *        {@link android.view.View#FOCUS_DOWN}.
 * @return The position of the next selectable position of the views that
 *         are currently visible, taking into account the fact that there might
 *         be no selection.  Returns {@link #INVALID_POSITION} if there is no
 *         selectable view on screen in the given direction.
 *//*w  w  w  .j a v  a  2 s . c  o m*/
private int lookForSelectablePositionOnScreen(int direction) {
    final int firstPosition = mFirstPosition;
    if (direction == View.FOCUS_DOWN) {
        int startPos = (mSelectedPosition != INVALID_POSITION) ? mSelectedPosition + 1 : firstPosition;
        if (startPos >= mAdapter.getCount()) {
            return INVALID_POSITION;
        }
        if (startPos < firstPosition) {
            startPos = firstPosition;
        }

        final int lastVisiblePos = getLastVisiblePosition();
        final ListAdapter adapter = getAdapter();
        for (int pos = startPos; pos <= lastVisiblePos; pos++) {
            if (adapter.isEnabled(pos) && getChildAt(pos - firstPosition).getVisibility() == View.VISIBLE) {
                return pos;
            }
        }
    } else {
        int last = firstPosition + getChildCount() - 1;
        int startPos = (mSelectedPosition != INVALID_POSITION) ? mSelectedPosition - 1
                : firstPosition + getChildCount() - 1;
        if (startPos < 0 || startPos >= mAdapter.getCount()) {
            return INVALID_POSITION;
        }
        if (startPos > last) {
            startPos = last;
        }

        final ListAdapter adapter = getAdapter();
        for (int pos = startPos; pos >= firstPosition; pos--) {
            if (adapter.isEnabled(pos) && getChildAt(pos - firstPosition).getVisibility() == View.VISIBLE) {
                return pos;
            }
        }
    }
    return INVALID_POSITION;
}

From source file:android.support.v17.leanback.widget.GridLayoutManager.java

@Override
public View onInterceptFocusSearch(View focused, int direction) {
    if (mFocusSearchDisabled) {
        return focused;
    }/*ww w.  jav  a2  s.c  o  m*/

    final FocusFinder ff = FocusFinder.getInstance();
    View result = null;
    if (direction == View.FOCUS_FORWARD || direction == View.FOCUS_BACKWARD) {
        // convert direction to absolute direction and see if we have a view there and if not
        // tell LayoutManager to add if it can.
        if (canScrollVertically()) {
            final int absDir = direction == View.FOCUS_FORWARD ? View.FOCUS_DOWN : View.FOCUS_UP;
            result = ff.findNextFocus(mBaseGridView, focused, absDir);
        }
        if (canScrollHorizontally()) {
            boolean rtl = getLayoutDirection() == ViewCompat.LAYOUT_DIRECTION_RTL;
            final int absDir = (direction == View.FOCUS_FORWARD) ^ rtl ? View.FOCUS_RIGHT : View.FOCUS_LEFT;
            result = ff.findNextFocus(mBaseGridView, focused, absDir);
        }
    } else {
        result = ff.findNextFocus(mBaseGridView, focused, direction);
    }
    if (result != null) {
        return result;
    }

    if (DEBUG)
        Log.v(getTag(), "regular focusSearch failed direction " + direction);
    int movement = getMovement(direction);
    final boolean isScroll = mBaseGridView.getScrollState() != RecyclerView.SCROLL_STATE_IDLE;
    if (movement == NEXT_ITEM) {
        if (isScroll || !mFocusOutEnd) {
            result = focused;
        }
        if (mScrollEnabled && !hasCreatedLastItem()) {
            processPendingMovement(true);
            result = focused;
        }
    } else if (movement == PREV_ITEM) {
        if (isScroll || !mFocusOutFront) {
            result = focused;
        }
        if (mScrollEnabled && !hasCreatedFirstItem()) {
            processPendingMovement(false);
            result = focused;
        }
    } else if (movement == NEXT_ROW) {
        if (isScroll || !mFocusOutSideEnd) {
            result = focused;
        }
    } else if (movement == PREV_ROW) {
        if (isScroll || !mFocusOutSideStart) {
            result = focused;
        }
    }
    if (result != null) {
        return result;
    }

    if (DEBUG)
        Log.v(getTag(), "now focusSearch in parent");
    result = mBaseGridView.getParent().focusSearch(focused, direction);
    if (result != null) {
        return result;
    }
    return focused != null ? focused : mBaseGridView;
}