ViewPager2在TV端适配

先贴代码,后续分析

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

、、、

你可能感兴趣的:(ViewPager2在TV端适配)