Example usage for android.view FocusFinder findNextFocus

List of usage examples for android.view FocusFinder findNextFocus

Introduction

In this page you can find the example usage for android.view FocusFinder findNextFocus.

Prototype

public final View findNextFocus(ViewGroup root, View focused, int direction) 

Source Link

Document

Find the next view to take focus in root's descendants, starting from the view that currently is focused.

Usage

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

@Override
public View focusSearch(View focused, int direction) {
    // Step.1 search focus by onInterceptFocusSearch
    View result = getLayoutManager().onInterceptFocusSearch(focused, direction);
    if (result != null) {
        return result;
    }//from w w w.  j  a  v  a 2  s.com
    // Step.2 search focus by FocusFinder
    final FocusFinder ff = FocusFinder.getInstance();
    result = ff.findNextFocus(this, focused, direction);
    if (result != null) {
        return result;
    }
    // Step.3 search focus by onFocusSearchFailed
    if (getLayoutManager() instanceof GridLayoutManager) {
        GridLayoutManager layoutManager = (GridLayoutManager) getLayoutManager();
        if (layoutManager.ensureRecyclerState()) {
            result = layoutManager.onFocusSearchFailed(focused, direction, layoutManager.getRecycler(),
                    layoutManager.getState());
            if (result != null) {
                return result;
            }
        }
    }

    if (direction == FOCUS_DOWN) {
        final int position = getLayoutManager().getPosition(focused);
        if (position < getLayoutManager().getItemCount() - 1) {
            forceRequestLayout();
        }
    }

    return null;
}

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

/**
 * You must override this method if RecyclerView need to page loading and you need to handle
 * the problem of Focus jitter/*from ww w.  j  a  v a 2 s. co m*/
 *
 * @param focused   focused The view that currently has focus
 * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and
 *                  FOCUS_RIGHT, or 0 for not applicable.
 * @return the result of focusSearch
 */
@Override
public View focusSearch(View focused, int direction) {
    // Step.1 search focus by onInterceptFocusSearch
    View result = getLayoutManager().onInterceptFocusSearch(focused, direction);
    if (result != null) {
        return result;
    }
    // Step.2 search focus by FocusFinder
    final FocusFinder ff = FocusFinder.getInstance();
    result = ff.findNextFocus(this, focused, direction);
    if (result != null) {
        return result;
    }
    // Step.3 search focus by onFocusSearchFailed
    if (getLayoutManager() instanceof GridLayoutManager) {
        GridLayoutManager layoutManager = (GridLayoutManager) getLayoutManager();
        if (layoutManager.ensureRecyclerState()) {
            result = layoutManager.onFocusSearchFailed(focused, direction, layoutManager.getRecycler(),
                    layoutManager.getState());
            if (result != null) {
                return result;
            }
        }
    }

    if (direction == FOCUS_RIGHT) {
        final int position = getLayoutManager().getPosition(focused);
        if (position < getLayoutManager().getItemCount() - 1) {
            forceRequestLayout();
        }
    }

    return null;
}

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

@Override
public View onInterceptFocusSearch(View focused, int direction) {
    if (mFocusSearchDisabled) {
        return focused;
    }//  ww w  .  j a va 2 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;
}

From source file:android.support.v7.widget.RecyclerView.java

@Override
public View focusSearch(View focused, int direction) {
    View result = mLayout.onInterceptFocusSearch(focused, direction);
    if (result != null) {
        return result;
    }/* ww w  .  j  a v  a2 s  . c  o m*/
    final FocusFinder ff = FocusFinder.getInstance();
    result = ff.findNextFocus(this, focused, direction);
    if (result == null && mAdapter != null) {
        eatRequestLayout();
        result = mLayout.onFocusSearchFailed(focused, direction, mRecycler, mState);
        resumeRequestLayout(false);
    }
    return result != null ? result : super.focusSearch(focused, direction);
}

From source file:org.nekC.android.support.widget.RecyclerView.java

@Override
public View focusSearch(View focused, int direction) {
    View result = mLayout.onInterceptFocusSearch(focused, direction);
    if (result != null) {
        return result;
    }// ww  w.j a v a  2s  .  co m
    final FocusFinder ff = FocusFinder.getInstance();
    result = ff.findNextFocus(this, focused, direction);
    if (result == null && mAdapter != null && mLayout != null) {
        eatRequestLayout();
        result = mLayout.onFocusSearchFailed(focused, direction, mRecycler, mState);
        resumeRequestLayout(false);
    }
    return result != null ? result : super.focusSearch(focused, direction);
}

From source file:android.support.v71.widget.RecyclerView.java

@Override
public View focusSearch(View focused, int direction) {
    View result = mLayout.onInterceptFocusSearch(focused, direction);
    if (result != null) {
        return result;
    }//from w w w  . j av a 2 s .  c o  m
    final FocusFinder ff = FocusFinder.getInstance();
    result = ff.findNextFocus(this, focused, direction);
    if (result == null && mAdapter != null && mLayout != null && !isComputingLayout() && !mLayoutFrozen) {
        eatRequestLayout();
        result = mLayout.onFocusSearchFailed(focused, direction, mRecycler, mState);
        resumeRequestLayout(false);
    }
    return result != null ? result : super.focusSearch(focused, direction);
}

From source file:cn.ismartv.tvrecyclerview.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 . jav a2  s . c  om
 * <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 (!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 (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.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.//from   ww  w.j  av  a 2 s  . com
 * <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);
}