下面列出了android.view.View#FOCUS_UP 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private int getMovement(int direction) {
if (mOrientation == VERTICAL) {
if (direction == View.FOCUS_UP) {
return mShouldReverseLayout ? DIRECTION_FORWARD : DIRECTION_BACKWARD;
} else if (direction == View.FOCUS_DOWN) {
return mShouldReverseLayout ? DIRECTION_BACKWARD : DIRECTION_FORWARD;
} else {
return DIRECTION_NO_WHERE;
}
} else {
if (direction == View.FOCUS_LEFT) {
return mShouldReverseLayout ? DIRECTION_FORWARD : DIRECTION_BACKWARD;
} else if (direction == View.FOCUS_RIGHT) {
return mShouldReverseLayout ? DIRECTION_BACKWARD : DIRECTION_FORWARD;
} else {
return DIRECTION_NO_WHERE;
}
}
}
/**
* <p>Scrolls the view to make the area defined by <code>top</code> and
* <code>bottom</code> visible. This method attempts to give the focus
* to a component visible in this area. If no component can be focused in
* the new visible area, the focus is reclaimed by this ScrollView.</p>
*
* @param direction the scroll direction: {@link View#FOCUS_UP}
* to go upward, {@link View#FOCUS_DOWN} to downward
* @param top the top offset of the new area to be made visible
* @param bottom the bottom offset of the new area to be made visible
* @return true if the key event is consumed by this method, false otherwise
*/
private boolean scrollAndFocus(int direction, int top, int bottom) {
boolean handled = true;
int height = getHeight();
int containerTop = getScrollY();
int containerBottom = containerTop + height;
boolean up = direction == View.FOCUS_UP;
View newFocused = findFocusableViewInBounds(up, top, bottom);
if (newFocused == null) {
newFocused = this;
}
if (top >= containerTop && bottom <= containerBottom) {
handled = false;
} else {
int delta = up ? (top - containerTop) : (bottom - containerBottom);
doScrollY(delta);
}
if (newFocused != findFocus()) newFocused.requestFocus(direction);
return handled;
}
/**
* When looking for focus in children of a scroll view, need to be a little
* more careful not to give focus to something that is scrolled off screen.
* <p/>
* This is more expensive than the default {@link android.view.ViewGroup}
* implementation, otherwise this behavior might have been made the default.
*/
@Override
protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
// convert from forward / backward notation to up / down / left / right
// (ugh).
if (direction == View.FOCUS_FORWARD) {
direction = View.FOCUS_DOWN;
} else if (direction == View.FOCUS_BACKWARD) {
direction = View.FOCUS_UP;
}
final View nextFocus = previouslyFocusedRect == null ?
FocusFinder.getInstance().findNextFocus(this, null, direction) :
FocusFinder.getInstance().findNextFocusFromRect(this,
previouslyFocusedRect, direction);
if (nextFocus == null) {
return false;
}
return nextFocus.requestFocus(direction, previouslyFocusedRect);
}
/**
* When looking for focus in children of a scroll view, need to be a little
* more careful not to give focus to something that is scrolled off screen.
* <p/>
* This is more expensive than the default {@link android.view.ViewGroup}
* implementation, otherwise this behavior might have been made the default.
*/
@Override
protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
// convert from forward / backward notation to up / down / left / right
// (ugh).
if (direction == View.FOCUS_FORWARD) {
direction = View.FOCUS_DOWN;
} else if (direction == View.FOCUS_BACKWARD) {
direction = View.FOCUS_UP;
}
final View nextFocus = previouslyFocusedRect == null ?
FocusFinder.getInstance().findNextFocus(this, null, direction) :
FocusFinder.getInstance().findNextFocusFromRect(this,
previouslyFocusedRect, direction);
if (nextFocus == null) {
return false;
}
return nextFocus.requestFocus(direction, previouslyFocusedRect);
}
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);
}
}
/**
* <p>
* Scrolls the view to make the area defined by <code>top</code> and
* <code>bottom</code> visible. This method attempts to give the focus to a
* component visible in this area. If no component can be focused in the new
* visible area, the focus is reclaimed by this scrollview.
* </p>
*
* @param direction the scroll direction: {@link View#FOCUS_UP} to go
* upward {@link View#FOCUS_DOWN} to downward
* @param top the top offset of the new area to be made visible
* @param bottom the bottom offset of the new area to be made visible
* @return true if the key event is consumed by this method, false otherwise
*/
private boolean scrollAndFocus(int direction, int top, int bottom) {
boolean handled = true;
int height = getHeight();
int containerTop = getScrollY();
int containerBottom = containerTop + height;
boolean up = direction == View.FOCUS_UP;
View newFocused = findFocusableViewInBounds(up, top, bottom);
if (newFocused == null) {
newFocused = this;
}
if ((top >= containerTop) && (bottom <= containerBottom)) {
handled = false;
} else {
int delta = up ? (top - containerTop) : (bottom - containerBottom);
doScrollY(delta);
}
if ((newFocused != findFocus()) && newFocused.requestFocus(direction)) {
mScrollViewMovedFocus = true;
mScrollViewMovedFocus = false;
}
return handled;
}
/**
* When looking for focus in children of a scroll view, need to be a little
* more careful not to give focus to something that is scrolled off screen.
*
* This is more expensive than the default {@link android.view.ViewGroup}
* implementation, otherwise this behavior might have been made the default.
*/
@Override
protected boolean onRequestFocusInDescendants(int direction,
Rect previouslyFocusedRect) {
// convert from forward / backward notation to up / down / left / right
// (ugh).
if (direction == View.FOCUS_FORWARD) {
direction = View.FOCUS_DOWN;
} else if (direction == View.FOCUS_BACKWARD) {
direction = View.FOCUS_UP;
}
final View nextFocus = previouslyFocusedRect == null ?
FocusFinder.getInstance().findNextFocus(this, null, direction) :
FocusFinder.getInstance().findNextFocusFromRect(this,
previouslyFocusedRect, direction);
if (nextFocus == null) {
return false;
}
if (isOffScreen(nextFocus)) {
return false;
}
return nextFocus.requestFocus(direction, previouslyFocusedRect);
}
/**
* 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;
}
}
/**
* 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 convertFocusDirectionToLayoutDirectionExpose(int focusDirection) {
int orientation = getOrientation();
switch (focusDirection) {
case View.FOCUS_BACKWARD:
return LayoutState.LAYOUT_START;
case View.FOCUS_FORWARD:
return LayoutState.LAYOUT_END;
case View.FOCUS_UP:
return orientation == VERTICAL ? LayoutState.LAYOUT_START
: LayoutState.INVALID_LAYOUT;
case View.FOCUS_DOWN:
return orientation == VERTICAL ? LayoutState.LAYOUT_END
: LayoutState.INVALID_LAYOUT;
case View.FOCUS_LEFT:
return orientation == HORIZONTAL ? LayoutState.LAYOUT_START
: LayoutState.INVALID_LAYOUT;
case View.FOCUS_RIGHT:
return orientation == HORIZONTAL ? LayoutState.LAYOUT_END
: LayoutState.INVALID_LAYOUT;
default:
if (DEBUG) {
Log.d(TAG, "Unknown focus request:" + focusDirection);
}
return LayoutState.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.
*/
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;
}
}
/**
* 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 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);
}
@Override
public boolean dispatchUnhandledMove(View focused, int direction) {
OPENLOG.E("direction:" + direction);
if (direction == View.FOCUS_DOWN) {
OPENLOG.E("direction FOCUS_DOWN:" + direction);
} else if (direction == View.FOCUS_UP) {
OPENLOG.E("direction FOCUS_UP:" + direction);
}
return super.dispatchUnhandledMove(focused, direction);
}
/**
* 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;
}
/**
* 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 RenderState#LAYOUT_START} or {@link RenderState#LAYOUT_END} if focus direction
* is applicable to current state, {@link 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;
}
}
private boolean scrollAndFocus(int directionY, int top, int bottom, int directionX, int left, int right) {
boolean handled = true;
int height = getHeight();
int containerTop = getScrollY();
int containerBottom = containerTop + height;
boolean up = directionY == View.FOCUS_UP;
int width = getWidth();
int containerLeft = getScrollX();
int containerRight = containerLeft + width;
boolean leftwards = directionX == View.FOCUS_UP;
View newFocused = findFocusableViewInBounds(up, top, bottom, leftwards, left, right);
if (newFocused == null) {
newFocused = this;
}
if ((top >= containerTop && bottom <= containerBottom) || (left >= containerLeft && right <= containerRight)) {
handled = false;
} else {
int deltaY = up ? (top - containerTop) : (bottom - containerBottom);
int deltaX = leftwards ? (left - containerLeft) : (right - containerRight);
doScroll(deltaX, deltaY);
}
if (newFocused != findFocus() && newFocused.requestFocus(directionY)) {
mTwoDScrollViewMovedFocus = true;
mTwoDScrollViewMovedFocus = false;
}
return handled;
}
/**
* Is childIndex a candidate for next focus given the direction the focus
* change is coming from?
* @param childIndex The index to check.
* @param direction The direction, one of
* {FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT, FOCUS_FORWARD, FOCUS_BACKWARD}
* @return Whether childIndex is a candidate.
*/
private boolean isCandidateSelection(int childIndex, int direction) {
final int count = getChildCount();
final int invertedIndex = count - 1 - childIndex;
int rowStart;
int rowEnd;
if (!mStackFromBottom) {
rowStart = childIndex - (childIndex % mNumColumns);
rowEnd = Math.min(rowStart + mNumColumns - 1, count);
} else {
rowEnd = count - 1 - (invertedIndex - (invertedIndex % mNumColumns));
rowStart = Math.max(0, rowEnd - mNumColumns + 1);
}
switch (direction) {
case View.FOCUS_RIGHT:
// coming from left, selection is only valid if it is on left
// edge
return childIndex == rowStart;
case View.FOCUS_DOWN:
// coming from top; only valid if in top row
return rowStart == 0;
case View.FOCUS_LEFT:
// coming from right, must be on right edge
return childIndex == rowEnd;
case View.FOCUS_UP:
// coming from bottom, need to be in last row
return rowEnd == count - 1;
case View.FOCUS_FORWARD:
// coming from top-left, need to be first in top row
return childIndex == rowStart && rowStart == 0;
case View.FOCUS_BACKWARD:
// coming from bottom-right, need to be last in bottom row
return childIndex == rowEnd && rowEnd == count - 1;
default:
throw new IllegalArgumentException("direction must be one of "
+ "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT, "
+ "FOCUS_FORWARD, FOCUS_BACKWARD}.");
}
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
final boolean handled = super.dispatchKeyEvent(event);
// unhandled key events change focus to tab indicator for embedded
// activities when there is nothing that will take focus from default
// focus searching
if (!handled
&& (event.getAction() == KeyEvent.ACTION_DOWN)
&& (mCurrentView != null)
&& (mCurrentView.isRootNamespace())
&& (mCurrentView.hasFocus())) {
int keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_UP;
int directionShouldChangeFocus = View.FOCUS_UP;
int soundEffect = SoundEffectConstants.NAVIGATION_UP;
switch (getTabWidgetLocation()) {
case TABWIDGET_LOCATION_LEFT:
keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_LEFT;
directionShouldChangeFocus = View.FOCUS_LEFT;
soundEffect = SoundEffectConstants.NAVIGATION_LEFT;
break;
case TABWIDGET_LOCATION_RIGHT:
keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_RIGHT;
directionShouldChangeFocus = View.FOCUS_RIGHT;
soundEffect = SoundEffectConstants.NAVIGATION_RIGHT;
break;
case TABWIDGET_LOCATION_BOTTOM:
keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_DOWN;
directionShouldChangeFocus = View.FOCUS_DOWN;
soundEffect = SoundEffectConstants.NAVIGATION_DOWN;
break;
case TABWIDGET_LOCATION_TOP:
default:
keyCodeShouldChangeFocus = KeyEvent.KEYCODE_DPAD_UP;
directionShouldChangeFocus = View.FOCUS_UP;
soundEffect = SoundEffectConstants.NAVIGATION_UP;
break;
}
if (event.getKeyCode() == keyCodeShouldChangeFocus
&& mCurrentView.findFocus().focusSearch(directionShouldChangeFocus) == null) {
mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus();
playSoundEffect(soundEffect);
return true;
}
}
return handled;
}
public boolean arrowScroll(int direction) {
View currentFocused = findFocus();
if (currentFocused == this) {
currentFocused = null;
} 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;
}
public boolean arrowScroll(int direction) {
View currentFocused = findFocus();
if (currentFocused == this) {
currentFocused = null;
} 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;
}