先贴代码,后续分析
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (mRecyclerView.getScrollState() != SCROLL_STATE_IDLE) {
return true;
}
return super.dispatchKeyEvent(event) || executeKeyEvent(event);
}
private boolean executeKeyEvent(KeyEvent event) {
boolean handled = false;
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_DPAD_LEFT:
handled = arrowScroll(FOCUS_LEFT);
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
handled = arrowScroll(FOCUS_RIGHT);
break;
case KeyEvent.KEYCODE_DPAD_UP:
handled = arrowScroll(FOCUS_UP);
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
handled = arrowScroll(FOCUS_DOWN);
break;
}
}
return handled;
}
private boolean arrowScroll(int direction) {
if (mRecyclerView.getScrollState() != SCROLL_STATE_IDLE) {
return false;
}
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("ViewPagerTV", "arrowScroll tried to find focus based on non-child " +
"current focused view " + sb.toString());
currentFocused = null;
}
}
boolean handled = false;
ViewGroup viewByPosition = (ViewGroup) mLayoutManager.findViewByPosition(mCurrentItem);
View nextFocused = FocusFinder.getInstance().findNextFocus(mRecyclerView, currentFocused,
direction);
if (getOrientation() == ORIENTATION_HORIZONTAL) {
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.
final int nextLeft = getChildRectInPagerCoordinates(mTempRect, nextFocused).left;
final int currLeft = getChildRectInPagerCoordinates(mTempRect, currentFocused).left;
Log.d(TAG, "FOCUS_LEFT: nextLeft=" + nextLeft + ", currLeft=" + currLeft);
Log.d(TAG, "FOCUS_LEFT: nextLeft=" + nextFocused + ", currLeft=" + currentFocused);
if (currentFocused != null && nextLeft < 0 || nextLeft >= currLeft) {
nextFocused.requestLayout();
nextFocused.requestFocus();
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.
final int nextLeft = getChildRectInPagerCoordinates(mTempRect, nextFocused).left;
final int currLeft = getChildRectInPagerCoordinates(mTempRect, currentFocused).left;
Log.d(TAG, "FOCUS_LEFT: nextLeft=" + nextLeft + ", currLeft=" + currLeft);
int maxWidth;
if (viewByPosition == null) {
maxWidth = (int) widthPixels;
} else {
maxWidth = viewByPosition.getMeasuredWidth();
}
if (currentFocused != null && nextLeft > maxWidth) {
nextFocused.requestLayout();
nextFocused.requestFocus();
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();
}
} else {
if (nextFocused != null && nextFocused != currentFocused) {
if (direction == View.FOCUS_UP) {
// 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 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 nextTop = getChildRectInPagerCoordinates(mTempRect, nextFocused).top;
final int currTop = getChildRectInPagerCoordinates(mTempRect, currentFocused).top;
if (currentFocused != null && nextTop <= currTop) {
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;
}
private Rect getChildRectInPagerCoordinates(Rect outRect, View child) {
if (outRect == null) {
outRect = new Rect();
}
if (child == null) {
outRect.set(0, 0, 0, 0);
return outRect;
}
outRect.left = child.getLeft();
outRect.right = child.getRight();
outRect.top = child.getTop();
outRect.bottom = child.getBottom();
ViewParent parent = child.getParent();
while (parent instanceof ViewGroup && parent != this) {
final ViewGroup group = (ViewGroup) parent;
outRect.left += group.getLeft();
outRect.right += group.getRight();
outRect.top += group.getTop();
outRect.bottom += group.getBottom();
parent = group.getParent();
}
Log.d(TAG, "getChildRectInPagerCoordinates: " + outRect.toString());
return outRect;
}
boolean pageLeft() {
Log.d(TAG, "pageLeft: ");
if (mCurrentItem > 0) {
setCurrentItem(mCurrentItem - 1, true);
return true;
}
return false;
}
boolean pageRight() {
Log.d(TAG, "pageRight: ");
if (getAdapter() != null && mCurrentItem < (mAdapter.getItemCount() - 1)) {
setCurrentItem(mCurrentItem + 1, true);
return true;
}
return false;
}
boolean pageUp() {
if (mCurrentItem > 0) {
setCurrentItem(mCurrentItem - 1, true);
return true;
}
return false;
}
boolean pageDown() {
if (mAdapter != null && mCurrentItem < (mAdapter.getItemCount() - 1)) {
setCurrentItem(mCurrentItem + 1, true);
return true;
}
return false;
}
、、、