Example usage for android.view View FOCUS_FORWARD

List of usage examples for android.view View FOCUS_FORWARD

Introduction

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

Prototype

int FOCUS_FORWARD

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

Click Source Link

Document

Use with #focusSearch(int) .

Usage

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

/**
 * Checks if the new focus candidate is a good enough candidate such that RecyclerView will
 * assign it as the next focus View instead of letting view hierarchy decide.
 * A good candidate means a View that is aligned in the focus direction wrt the focused View
 * and is not the RecyclerView itself.//from w  ww . j  a  v a2 s  .  c  om
 * When this method returns false, RecyclerView will let the parent make the decision so the
 * same View may still get the focus as a result of that search.
 */
private boolean isPreferredNextFocus(View focused, View next, int direction) {
    if (next == null || next == this) {
        return false;
    }
    if (focused == null) {
        return true;
    }

    if (direction == View.FOCUS_FORWARD || direction == View.FOCUS_BACKWARD) {
        final boolean rtl = mLayout.getLayoutDirection() == ViewCompat.LAYOUT_DIRECTION_RTL;
        final int absHorizontal = (direction == View.FOCUS_FORWARD) ^ rtl ? View.FOCUS_RIGHT : View.FOCUS_LEFT;
        if (isPreferredNextFocusAbsolute(focused, next, absHorizontal)) {
            return true;
        }
        if (direction == View.FOCUS_FORWARD) {
            return isPreferredNextFocusAbsolute(focused, next, View.FOCUS_DOWN);
        } else {
            return isPreferredNextFocusAbsolute(focused, next, View.FOCUS_UP);
        }
    } else {
        return isPreferredNextFocusAbsolute(focused, next, direction);
    }

}

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./*ww w. ja va2 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.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 ww w  .  j  av  a 2  s. c o m
 * @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:android.support.v17.leanback.widget.GridLayoutManager.java

@Override
public View onInterceptFocusSearch(View focused, int direction) {
    if (mFocusSearchDisabled) {
        return focused;
    }//from  ww  w .  j a v  a 2 s  . com

    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;
}

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

private boolean gridOnRequestFocusInDescendantsUnaligned(RecyclerView recyclerView, int direction,
        Rect previouslyFocusedRect) {/*from   w w w.  java  2  s. c om*/
    // focus to view not overlapping padding area to avoid scrolling in gaining focus
    int index;
    int increment;
    int end;
    int count = getChildCount();
    if ((direction & View.FOCUS_FORWARD) != 0) {
        index = 0;
        increment = 1;
        end = count;
    } else {
        index = count - 1;
        increment = -1;
        end = -1;
    }
    int left = mWindowAlignment.mainAxis().getPaddingLow();
    int right = mWindowAlignment.mainAxis().getClientSize() + left;
    for (int i = index; i != end; i += increment) {
        View child = getChildAt(i);
        if (child.getVisibility() == View.VISIBLE) {
            if (getViewMin(child) >= left && getViewMax(child) <= right) {
                if (child.requestFocus(direction, previouslyFocusedRect)) {
                    return true;
                }
            }
        }
    }
    return false;
}

From source file:com.appunite.list.AbsHorizontalListView.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 www.  j  av  a  2s  .c  o  m*/
 * @param dest the destination rectangle
 * @param direction the direction
 * @return the distance between the rectangles
 */
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;
}