下面列出了android.view.View#FOCUS_LEFT 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/** Converts {@link TraversalStrategy.SearchDirection} to view focus direction. */
public static int nodeSearchDirectionToViewSearchDirection(
@TraversalStrategy.SearchDirection int direction) {
switch (direction) {
case TraversalStrategy.SEARCH_FOCUS_FORWARD:
return View.FOCUS_FORWARD;
case TraversalStrategy.SEARCH_FOCUS_BACKWARD:
return View.FOCUS_BACKWARD;
case TraversalStrategy.SEARCH_FOCUS_LEFT:
return View.FOCUS_LEFT;
case TraversalStrategy.SEARCH_FOCUS_RIGHT:
return View.FOCUS_RIGHT;
case TraversalStrategy.SEARCH_FOCUS_UP:
return View.FOCUS_UP;
case TraversalStrategy.SEARCH_FOCUS_DOWN:
return View.FOCUS_DOWN;
default:
throw new IllegalArgumentException("Direction must be a SearchDirection");
}
}
@Override
public boolean dispatchUnhandledMove(View focused, int direction) {
// XXX-RTL: This will be fixed in a future CL
if (direction == View.FOCUS_LEFT) {
if (getCurrentPage() > 0) {
snapToPage(getCurrentPage() - 1);
return true;
}
} else if (direction == View.FOCUS_RIGHT) {
if (getCurrentPage() < getPageCount() - 1) {
snapToPage(getCurrentPage() + 1);
return true;
}
}
return super.dispatchUnhandledMove(focused, direction);
}
private int getAlignedScrollPrimary(View view) {
int distance;
if (mOrientation == HORIZONTAL) {
if (mDirection != DEFAULT_DIRECTION) {
if (mDirection == View.FOCUS_UP || mDirection == View.FOCUS_DOWN) {
return 0;
}
}
distance = view.getLeft() +
view.getWidth() / 2 - getClientSize() / 2 - getPaddingLeft();
} else {
if (mDirection != DEFAULT_DIRECTION) {
if (mDirection == View.FOCUS_LEFT || mDirection == View.FOCUS_RIGHT) {
return 0;
}
}
distance = view.getTop() +
view.getHeight() / 2 - getClientSize() / 2 - getPaddingTop();
}
return distance;
}
private void enforceValidFocusDirection(int direction) {
switch (direction) {
case View.FOCUS_DOWN:
case View.FOCUS_UP:
case View.FOCUS_LEFT:
case View.FOCUS_RIGHT:
case View.FOCUS_FORWARD:
case View.FOCUS_BACKWARD:
return;
default:
throw new IllegalArgumentException("Unknown direction: " + direction);
}
}
/**
* Converts a focusDirection to orientation.
*
* @param focusDirection One of {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN},
* {@link View#FOCUS_LEFT}, {@link View#FOCUS_RIGHT},
* {@link View#FOCUS_BACKWARD}, {@link View#FOCUS_FORWARD}
* or 0 for not applicable
* @return {@link LayoutState#LAYOUT_START} or {@link LayoutState#LAYOUT_END} if focus direction
* is applicable to current state, {@link LayoutState#INVALID_LAYOUT} otherwise.
*/
private int convertFocusDirectionToLayoutDirection(int focusDirection) {
switch (focusDirection) {
case View.FOCUS_BACKWARD:
if (mOrientation == VERTICAL) {
return LayoutState.LAYOUT_START;
} else if (isLayoutRTL()) {
return LayoutState.LAYOUT_END;
} else {
return LayoutState.LAYOUT_START;
}
case View.FOCUS_FORWARD:
if (mOrientation == VERTICAL) {
return LayoutState.LAYOUT_END;
} else if (isLayoutRTL()) {
return LayoutState.LAYOUT_START;
} else {
return LayoutState.LAYOUT_END;
}
case View.FOCUS_UP:
return mOrientation == VERTICAL ? LayoutState.LAYOUT_START
: LayoutState.INVALID_LAYOUT;
case View.FOCUS_DOWN:
return mOrientation == VERTICAL ? LayoutState.LAYOUT_END
: LayoutState.INVALID_LAYOUT;
case View.FOCUS_LEFT:
return mOrientation == HORIZONTAL ? LayoutState.LAYOUT_START
: LayoutState.INVALID_LAYOUT;
case View.FOCUS_RIGHT:
return mOrientation == HORIZONTAL ? LayoutState.LAYOUT_END
: LayoutState.INVALID_LAYOUT;
default:
if (DEBUG) {
Log.d(TAG, "Unknown focus request:" + focusDirection);
}
return LayoutState.INVALID_LAYOUT;
}
}
@Override
public View onFocusSearchFailed(@NonNull View focused, int focusDirection,
RecyclerView.Recycler recycler, RecyclerView.State state) {
View nextView = super.onFocusSearchFailed(focused, focusDirection, recycler, state);
if (nextView == null) {
if (mCircular) {
final int adapterPositionToJump;
if ((focusDirection == View.FOCUS_DOWN && getOrientation() == VERTICAL)
|| (focusDirection == View.FOCUS_RIGHT && getOrientation() == HORIZONTAL)) {
adapterPositionToJump = 0;
mPendingChildPositionToFocus = FIRST;
} else if ((focusDirection == View.FOCUS_UP && getOrientation() == VERTICAL)
|| (focusDirection == View.FOCUS_LEFT && getOrientation() == HORIZONTAL)) {
adapterPositionToJump = getItemCount() - 1;
mPendingChildPositionToFocus = LAST;
} else {
return null;
}
// Can't initiate scrolling because requesting layout is forbidden in this state
focused.post(new Runnable() {
@Override
public void run() {
scrollToPosition(adapterPositionToJump);
}
});
}
}
return null;
}
private int getMovement(int direction) {
int movement = View.FOCUS_LEFT;
if (mOrientation == HORIZONTAL) {
switch(direction) {
case View.FOCUS_LEFT:
movement = PREV_ITEM;
break;
case View.FOCUS_RIGHT:
movement = NEXT_ITEM;
break;
case View.FOCUS_UP:
movement = PREV_ROW;
break;
case View.FOCUS_DOWN:
movement = NEXT_ROW;
break;
}
} else if (mOrientation == VERTICAL) {
switch(direction) {
case View.FOCUS_LEFT:
movement = PREV_ROW;
break;
case View.FOCUS_RIGHT:
movement = NEXT_ROW;
break;
case View.FOCUS_UP:
movement = PREV_ITEM;
break;
case View.FOCUS_DOWN:
movement = NEXT_ITEM;
break;
}
}
return movement;
}
public boolean arrowScroll(int direction) {
View currentFocused = findFocus();
if (currentFocused == this) currentFocused = null;
boolean handled = false;
View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused,
direction);
if (nextFocused != null && nextFocused != currentFocused) {
if (direction == View.FOCUS_LEFT) {
handled = nextFocused.requestFocus();
} else if (direction == View.FOCUS_RIGHT) {
// 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.
if (currentFocused != null && nextFocused.getLeft() <= currentFocused.getLeft()) {
handled = pageRight();
} else {
handled = nextFocused.requestFocus();
}
}
} else if (direction == FOCUS_LEFT || direction == FOCUS_BACKWARD) {
// Trying to move left and nothing there; try to page.
handled = pageLeft();
} else if (direction == FOCUS_RIGHT || direction == FOCUS_FORWARD) {
// Trying to move right and nothing there; try to page.
handled = pageRight();
}
if (handled) {
playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction));
}
return handled;
}
@Override
public boolean takeFocus(boolean reverse) {
int direction =
(reverse == (mContainerView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL)) ?
View.FOCUS_RIGHT : View.FOCUS_LEFT;
if (tryToMoveFocus(direction)) return true;
direction = reverse ? View.FOCUS_UP : View.FOCUS_DOWN;
return tryToMoveFocus(direction);
}
public boolean arrowScroll(int direction) {
View currentFocused = findFocus();
if (currentFocused == this) currentFocused = null;
boolean handled = false;
View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused,
direction);
if (nextFocused != null && nextFocused != currentFocused) {
if (direction == View.FOCUS_LEFT) {
handled = nextFocused.requestFocus();
} else if (direction == View.FOCUS_RIGHT) {
// 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.
if (currentFocused != null && nextFocused.getLeft() <= currentFocused.getLeft()) {
handled = pageRight();
} else {
handled = nextFocused.requestFocus();
}
}
} else if (direction == FOCUS_LEFT || direction == FOCUS_BACKWARD) {
// Trying to move left and nothing there; try to page.
handled = pageLeft();
} else if (direction == FOCUS_RIGHT || direction == FOCUS_FORWARD) {
// Trying to move right and nothing there; try to page.
handled = pageRight();
}
if (handled) {
playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction));
}
return handled;
}
private boolean scrollAndFocusH(int direction, int left, int right) {
boolean handled = true;
int width = getWidth();
int containerLeft = getScrollX();
int containerRight = containerLeft + width;
boolean goLeft = direction == View.FOCUS_LEFT;
View newFocused = findFocusableViewInBoundsH(goLeft, left, right);
if (newFocused == null) {
newFocused = this;
}
if (left >= containerLeft && right <= containerRight) {
handled = false;
} else {
int delta = goLeft ? (left - containerLeft) : (right - containerRight);
doScrollX(delta);
}
if (newFocused != findFocus() && newFocused.requestFocus(direction)) {
mScrollViewMovedFocus = true;
mScrollViewMovedFocus = false;
}
return handled;
}
public boolean arrowScroll(int direction) {
View currentFocused = findFocus();
if (currentFocused == this) currentFocused = null;
boolean handled = false;
View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused,
direction);
if (nextFocused != null && nextFocused != currentFocused) {
if (direction == View.FOCUS_LEFT) {
// 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.
if (currentFocused != null && nextFocused.getLeft() >= currentFocused.getLeft()) {
handled = pageLeft();
} else {
handled = nextFocused.requestFocus();
}
} else if (direction == View.FOCUS_RIGHT) {
// 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.
if (currentFocused != null && nextFocused.getLeft() <= currentFocused.getLeft()) {
handled = pageRight();
} else {
handled = nextFocused.requestFocus();
}
}
} else if (direction == FOCUS_LEFT || direction == FOCUS_BACKWARD) {
// Trying to move left and nothing there; try to page.
handled = pageLeft();
} else if (direction == FOCUS_RIGHT || direction == FOCUS_FORWARD) {
// Trying to move right and nothing there; try to page.
handled = pageRight();
}
if (handled) {
playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction));
}
return handled;
}
/**
* Converts a focusDirection to orientation.
*
* @param focusDirection One of {@link android.view.View#FOCUS_UP}, {@link android.view.View#FOCUS_DOWN},
* {@link android.view.View#FOCUS_LEFT}, {@link android.view.View#FOCUS_RIGHT},
* {@link android.view.View#FOCUS_BACKWARD}, {@link android.view.View#FOCUS_FORWARD}
* or 0 for not applicable
* @return {@link com.twotoasters.android.support.v7.widget.LinearLayoutManager.RenderState#LAYOUT_START} or {@link com.twotoasters.android.support.v7.widget.LinearLayoutManager.RenderState#LAYOUT_END} if focus direction
* is applicable to current state, {@link com.twotoasters.android.support.v7.widget.LinearLayoutManager.RenderState#INVALID_LAYOUT} otherwise.
*/
private int convertFocusDirectionToLayoutDirection(int focusDirection) {
switch (focusDirection) {
case View.FOCUS_BACKWARD:
return RenderState.LAYOUT_START;
case View.FOCUS_FORWARD:
return RenderState.LAYOUT_END;
case View.FOCUS_UP:
return mOrientation == VERTICAL ? RenderState.LAYOUT_START
: RenderState.INVALID_LAYOUT;
case View.FOCUS_DOWN:
return mOrientation == VERTICAL ? RenderState.LAYOUT_END
: RenderState.INVALID_LAYOUT;
case View.FOCUS_LEFT:
return mOrientation == HORIZONTAL ? RenderState.LAYOUT_START
: RenderState.INVALID_LAYOUT;
case View.FOCUS_RIGHT:
return mOrientation == HORIZONTAL ? RenderState.LAYOUT_END
: RenderState.INVALID_LAYOUT;
default:
if (DEBUG) {
Log.d(TAG, "Unknown focus request:" + focusDirection);
}
return RenderState.INVALID_LAYOUT;
}
}
/**
* Converts a focusDirection to orientation.
*
* @param focusDirection One of {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN},
* {@link View#FOCUS_LEFT}, {@link View#FOCUS_RIGHT},
* {@link View#FOCUS_BACKWARD}, {@link View#FOCUS_FORWARD}
* or 0 for not applicable
* @return {@link LayoutState#LAYOUT_START} or {@link LayoutState#LAYOUT_END} if focus direction
* is applicable to current state, {@link LayoutState#INVALID_LAYOUT} otherwise.
*/
private int convertFocusDirectionToLayoutDirection(int focusDirection) {
switch (focusDirection) {
case View.FOCUS_BACKWARD:
return LayoutState.LAYOUT_START;
case View.FOCUS_FORWARD:
return LayoutState.LAYOUT_END;
case View.FOCUS_UP:
return mOrientation == VERTICAL ? LayoutState.LAYOUT_START
: LayoutState.INVALID_LAYOUT;
case View.FOCUS_DOWN:
return mOrientation == VERTICAL ? LayoutState.LAYOUT_END
: LayoutState.INVALID_LAYOUT;
case View.FOCUS_LEFT:
return mOrientation == HORIZONTAL ? LayoutState.LAYOUT_START
: LayoutState.INVALID_LAYOUT;
case View.FOCUS_RIGHT:
return mOrientation == HORIZONTAL ? LayoutState.LAYOUT_END
: LayoutState.INVALID_LAYOUT;
default:
if (DEBUG) {
Log.d(TAG, "Unknown focus request:" + focusDirection);
}
return LayoutState.INVALID_LAYOUT;
}
}
public boolean arrowScroll(int direction) {
View currentFocused = findFocus();
if (currentFocused == this) currentFocused = null;
boolean handled = false;
View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused,
direction);
if (nextFocused != null && nextFocused != currentFocused) {
if (direction == View.FOCUS_LEFT) {
handled = nextFocused.requestFocus();
} else if (direction == View.FOCUS_RIGHT) {
// 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.
if (currentFocused != null && nextFocused.getLeft() <= currentFocused.getLeft()) {
handled = pageRight();
} else {
handled = nextFocused.requestFocus();
}
}
} else if (direction == FOCUS_LEFT || direction == FOCUS_BACKWARD) {
// Trying to move left and nothing there; try to page.
handled = pageLeft();
} else if (direction == FOCUS_RIGHT || direction == FOCUS_FORWARD) {
// Trying to move right and nothing there; try to page.
handled = pageRight();
}
if (handled) {
playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction));
}
return handled;
}
@Override
public void addFocusables(ArrayList<View> views, int direction) {
getChildAt(mCurrentPage).addFocusables(views, direction);
if (direction == View.FOCUS_LEFT) {
if (mCurrentPage > 0) {
getChildAt(mCurrentPage - 1).addFocusables(views, direction);
}
} else if (direction == View.FOCUS_RIGHT) {
if (mCurrentPage < getChildCount() - 1) {
getChildAt(mCurrentPage + 1).addFocusables(views, direction);
}
}
}
private boolean scrollAndFocusH(int direction, int left, int right) {
boolean handled = true;
int width = getWidth();
int containerLeft = getScrollX();
int containerRight = containerLeft + width;
boolean goLeft = direction == View.FOCUS_LEFT;
View newFocused = findFocusableViewInBoundsH(goLeft, left, right);
if (newFocused == null) {
newFocused = this;
}
if (left >= containerLeft && right <= containerRight) {
handled = false;
} else {
int delta = goLeft ? (left - containerLeft)
: (right - containerRight);
doScrollX(delta);
}
if (newFocused != findFocus() && newFocused.requestFocus(direction)) {
mScrollViewMovedFocus = true;
mScrollViewMovedFocus = false;
}
return handled;
}
public boolean arrowScroll(int direction) {
View currentFocused = findFocus();
if (currentFocused == this) currentFocused = null;
boolean handled = false;
View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused,
direction);
if (nextFocused != null && nextFocused != currentFocused) {
if (direction == View.FOCUS_LEFT) {
handled = nextFocused.requestFocus();
} else if (direction == View.FOCUS_RIGHT) {
// 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.
if (currentFocused != null && nextFocused.getLeft() <= currentFocused.getLeft()) {
handled = pageRight();
} else {
handled = nextFocused.requestFocus();
}
}
} else if (direction == FOCUS_LEFT || direction == FOCUS_BACKWARD) {
// Trying to move left and nothing there; try to page.
handled = pageLeft();
} else if (direction == FOCUS_RIGHT || direction == FOCUS_FORWARD) {
// Trying to move right and nothing there; try to page.
handled = pageRight();
}
if (handled) {
playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction));
}
return handled;
}
/**
* 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
* @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;
default:
throw new IllegalArgumentException("direction must be one of "
+ "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT}.");
}
int deltaX = dX - sX;
int deltaY = dY - sY;
return deltaY * deltaY + deltaX * deltaX;
}
@Override
protected boolean onRequestFocusInDescendants(int direction,
Rect previouslyFocusedRect) {
// convert from forward / backward notation to up / down / left / right
// (ugh).
if(previouslyFocusedRect != null){
if (direction == View.FOCUS_FORWARD) {
direction = View.FOCUS_RIGHT;
} else if (direction == View.FOCUS_BACKWARD) {
direction = View.FOCUS_LEFT;
}
View nextFocus = FocusFinder.getInstance().findNextFocusFromRect(this,
previouslyFocusedRect, direction);
if (nextFocus == null) {
return false;
}
return nextFocus.requestFocus(direction, previouslyFocusedRect);
}else{
int index;
int increment;
int end;
int count = this.getChildCount();
if ((direction & FOCUS_FORWARD) != 0) {
index = 0;
increment = 1;
end = count;
} else {
index = count - 1;
increment = -1;
end = -1;
}
for (int i = index; i != end; i += increment) {
View child = this.getChildAt(i);
if (child.getVisibility()==View.VISIBLE) {
if (child.requestFocus(direction, previouslyFocusedRect)) {
return true;
}
}
}
return false;
}
}