private boolean handleHorizontalFocusWithinListItem(int direction) { if (direction == 33 || direction == 130) { int numChildren = getChildCount(); if (this.mItemsCanFocus && numChildren > 0 && this.mSelectedPosition != -1) { View selectedView = getSelectedView(); if (selectedView != null && selectedView.hasFocus() && (selectedView instanceof ViewGroup)) { View currentFocus = selectedView.findFocus(); View nextFocus = FocusFinder.getInstance().findNextFocus((ViewGroup) selectedView, currentFocus, direction); if (nextFocus != null) { currentFocus.getFocusedRect(this.mTempRect); offsetDescendantRectToMyCoords(currentFocus, this.mTempRect); offsetRectIntoDescendantCoords(nextFocus, this.mTempRect); if (nextFocus.requestFocus(direction, this.mTempRect)) { return true; } } View globalNextFocus = FocusFinder.getInstance().findNextFocus((ViewGroup) getRootView(), currentFocus, direction); if (globalNextFocus != null) { return isViewAncestorOf(globalNextFocus, this); } } } return false; } throw new IllegalArgumentException("direction must be one of {View.FOCUS_UP, View.FOCUS_DOWN}"); }
/** * 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); }
@Override public View focusSearch(View focused, int direction) { View result = mLayout.onInterceptFocusSearch(focused, direction); if (result != null) { return result; } 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); }
protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { if (direction == 2) { direction = 130; } else if (direction == 1) { direction = 33; } View nextFocus = previouslyFocusedRect == null ? FocusFinder.getInstance().findNextFocus(this, null, direction) : FocusFinder.getInstance().findNextFocusFromRect(this, previouslyFocusedRect, direction); if (nextFocus == null || isOffScreen(nextFocus)) { return false; } return nextFocus.requestFocus(direction, previouslyFocusedRect); }
/** * 获得滑动的方向 */ 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; }
/** * To avoid horizontal focus searches changing the selected item, we * manually focus search within the selected item (as applicable), and * prevent focus from jumping to something within another item. * * @param direction * one of {View.FOCUS_LEFT, View.FOCUS_RIGHT} * @return Whether this consumes the key event. */ private boolean handleHorizontalFocusWithinListItem(int direction) { // TODO: implement this if (direction != View.FOCUS_UP && direction != View.FOCUS_DOWN) { throw new IllegalArgumentException("direction must be one of" + " {View.FOCUS_UP, View.FOCUS_DOWN}"); } final int numChildren = getChildCount(); if (mItemsCanFocus && numChildren > 0 && mSelectedPosition != INVALID_POSITION) { final View selectedView = getSelectedView(); if (selectedView != null && selectedView.hasFocus() && selectedView instanceof ViewGroup) { final View currentFocus = selectedView.findFocus(); final View nextFocus = FocusFinder.getInstance().findNextFocus((ViewGroup) selectedView, currentFocus, direction); if (nextFocus != null) { // do the math to get interesting rect in next focus' // coordinates currentFocus.getFocusedRect(mTempRect); offsetDescendantRectToMyCoords(currentFocus, mTempRect); offsetRectIntoDescendantCoords(nextFocus, mTempRect); if (nextFocus.requestFocus(direction, mTempRect)) { return true; } } // we are blocking the key from being handled (by returning // true) // if the global result is going to be some other view within // this // list. this is to acheive the overall goal of having // horizontal d-pad navigation remain in the current item. final View globalNextFocus = FocusFinder.getInstance().findNextFocus((ViewGroup) getRootView(), currentFocus, direction); if (globalNextFocus != null) { return isViewAncestorOf(globalNextFocus, this); } } } return false; }
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; }
/** * 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); return nextFocus != null && 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 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); }
/** * 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 ViewGroup} * implementation, otherwise this behavior might have been made the default. */ @Override protected boolean onRequestFocusInDescendants(int direction, @Nullable 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; } View nextFocus = (previouslyFocusedRect == null) ? FocusFinder.getInstance().findNextFocus(this, null, direction) : FocusFinder.getInstance().findNextFocusFromRect(this, previouslyFocusedRect, direction); if (nextFocus == null) { return false; } return !isOffScreen(nextFocus) && 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. * * This is more expensive than the default {@link 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); }
public View focusSearch(View paramView, int paramInt) { View localView1 = this.mLayout.onInterceptFocusSearch(paramView, paramInt); if (localView1 != null) { return localView1; } View localView2 = FocusFinder.getInstance().findNextFocus(this, paramView, paramInt); if ((localView2 == null) && (this.mAdapter != null) && (this.mLayout != null) && (!isComputingLayout()) && (!this.mLayoutFrozen)) { eatRequestLayout(); localView2 = this.mLayout.onFocusSearchFailed$1539f5dc(paramInt, this.mRecycler, this.mState); resumeRequestLayout(false); } if (localView2 != null) { return localView2; } return super.focusSearch(paramView, paramInt); }
public View focusSearch(View paramView, int paramInt) { View localView = FocusFinder.getInstance().findNextFocus(this, paramView, paramInt); if ((localView == null) && (this.g != null) && (this.h != null)) { if (this.r <= 0) { break label82; } } label82: for (int i1 = 1;; i1 = 0) { if ((i1 == 0) && (!this.n)) { a(); localView = this.h.c(paramInt, this.b, this.y); a(false); } if (localView == null) { break; } return localView; } return super.focusSearch(paramView, paramInt); }
/** * 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 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); }
@Override protected void setUp() throws Exception { super.setUp(); mFocusFinder = FocusFinder.getInstance(); // inflate the layout final Context context = getContext(); final LayoutInflater inflater = LayoutInflater.from(context); mRoot = (ViewGroup) inflater.inflate(R.layout.focus_2, null); // manually measure it, and lay it out mRoot.measure(500, 500); mRoot.layout(0, 0, 500, 500); mLeftButton = (Button) mRoot.findViewById(R.id.leftButton); mCenterButton = (Button) mRoot.findViewById(R.id.centerButton); mRightButton = (Button) mRoot.findViewById(R.id.rightButton); }
/** * 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; } return nextFocus.requestFocus(direction, previouslyFocusedRect); }
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; }
/** * 找到下一个焦点的itemView * * @param focusView * @param vector * @param direction * @return */ private boolean findNextFocusView(View focusView, Point vector, int direction) { View nextFocus = FocusFinder.getInstance() .findNextFocus(this, focusView, direction); // Log.i(TAG, "right is null:" + (rightView == null)); if (nextFocus != null) { nextFocus.requestFocus(); return true; } else { this.smoothScrollBy(vector.x, vector.y); return true; } }
/** * Handle scrolling in response to a left or right arrow click. * * @param direction The direction corresponding to the arrow key that was pressed. It should be * either {@link View#FOCUS_LEFT} or {@link View#FOCUS_RIGHT}. * @return Whether the scrolling was handled successfully. */ 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; }
private ArrowScrollFocusResult arrowScrollFocused(int direction) { View newFocus; View selectedView = getSelectedView(); if (selectedView == null || !selectedView.hasFocus()) { int xSearchPoint; if (direction == 130) { int listLeft = this.mListPadding.left + (this.mFirstPosition > 0 ? getArrowScrollPreviewLength() : 0); if (selectedView == null || selectedView.getLeft() <= listLeft) { xSearchPoint = listLeft; } else { xSearchPoint = selectedView.getLeft(); } this.mTempRect.set(xSearchPoint, 0, xSearchPoint, 0); } else { int listRight = (getWidth() - this.mListPadding.right) - ((this.mFirstPosition + getChildCount()) + -1 < this.mItemCount ? getArrowScrollPreviewLength() : 0); if (selectedView == null || selectedView.getRight() >= listRight) { xSearchPoint = listRight; } else { xSearchPoint = selectedView.getRight(); } this.mTempRect.set(xSearchPoint, 0, xSearchPoint, 0); } newFocus = FocusFinder.getInstance().findNextFocusFromRect(this, this.mTempRect, direction); } else { newFocus = FocusFinder.getInstance().findNextFocus(this, selectedView.findFocus(), direction); } if (newFocus != null) { int positionOfNewFocus = positionOfNewFocus(newFocus); if (!(this.mSelectedPosition == -1 || positionOfNewFocus == this.mSelectedPosition)) { int selectablePosition = lookForSelectablePositionOnScreen(direction); if (selectablePosition != -1 && ((direction == 130 && selectablePosition < positionOfNewFocus) || (direction == 33 && selectablePosition > positionOfNewFocus))) { return null; } } int focusScroll = amountToScrollToNewFocus(direction, newFocus, positionOfNewFocus); int maxScrollAmount = getMaxScrollAmount(); if (focusScroll < maxScrollAmount) { newFocus.requestFocus(direction); this.mArrowScrollFocusResult.populate(positionOfNewFocus, focusScroll); return this.mArrowScrollFocusResult; } else if (distanceToView(newFocus) < maxScrollAmount) { newFocus.requestFocus(direction); this.mArrowScrollFocusResult.populate(positionOfNewFocus, maxScrollAmount); return this.mArrowScrollFocusResult; } } return null; }
public View focusSearch(View focused, int direction) { View result = this.mLayout.onInterceptFocusSearch(focused, direction); if (result != null) { return result; } result = FocusFinder.getInstance().findNextFocus(this, focused, direction); if (!(result != null || this.mAdapter == null || this.mLayout == null || isComputingLayout() || this.mLayoutFrozen)) { eatRequestLayout(); result = this.mLayout.onFocusSearchFailed(focused, direction, this.mRecycler, this.mState); resumeRequestLayout(false); } return result != null ? result : super.focusSearch(focused, direction); }
public boolean arrowScroll(int direction) { View currentFocused = findFocus(); if (currentFocused == this) { currentFocused = null; } else if (currentFocused != null) { boolean isChild = false; for (ViewPager parent = currentFocused.getParent(); parent instanceof ViewGroup; parent = parent.getParent()) { if (parent == this) { isChild = true; break; } } if (!isChild) { StringBuilder sb = new StringBuilder(); sb.append(currentFocused.getClass().getSimpleName()); for (ViewParent parent2 = currentFocused.getParent(); parent2 instanceof ViewGroup; parent2 = parent2.getParent()) { sb.append(" => ").append(parent2.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 == 17 || direction == 1) { handled = pageLeft(); } else if (direction == 66 || direction == 2) { handled = pageRight(); } } else if (direction == 17) { handled = (currentFocused == null || getChildRectInPagerCoordinates(this.mTempRect, nextFocused).left < getChildRectInPagerCoordinates(this.mTempRect, currentFocused).left) ? nextFocused.requestFocus() : pageLeft(); } else if (direction == 66) { handled = (currentFocused == null || getChildRectInPagerCoordinates(this.mTempRect, nextFocused).left > getChildRectInPagerCoordinates(this.mTempRect, currentFocused).left) ? nextFocused.requestFocus() : pageRight(); } if (handled) { playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction)); } return handled; }
public boolean executeKeyEvent(KeyEvent event) { this.mTempRect.setEmpty(); if (canScroll()) { boolean handled = false; if (event.getAction() == 0) { switch (event.getKeyCode()) { case 19: if (!event.isAltPressed()) { handled = arrowScroll(33); break; } handled = fullScroll(33); break; case 20: if (!event.isAltPressed()) { handled = arrowScroll(130); break; } handled = fullScroll(130); break; case 62: pageScroll(event.isShiftPressed() ? 33 : 130); break; } } return handled; } else if (!isFocused() || event.getKeyCode() == 4) { return false; } else { View currentFocused = findFocus(); if (currentFocused == this) { currentFocused = null; } View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, 130); if (nextFocused == null || nextFocused == this || !nextFocused.requestFocus(130)) { return false; } return true; } }
public boolean arrowScroll(int direction) { View currentFocused = findFocus(); if (currentFocused == this) { currentFocused = null; } View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, direction); int maxJump = getMaxScrollAmount(); if (nextFocused == null || !isWithinDeltaOfScreen(nextFocused, maxJump, getHeight())) { int scrollDelta = maxJump; if (direction == 33 && getScrollY() < scrollDelta) { scrollDelta = getScrollY(); } else if (direction == 130 && getChildCount() > 0) { int daBottom = getChildAt(0).getBottom(); int screenBottom = (getScrollY() + getHeight()) - getPaddingBottom(); if (daBottom - screenBottom < maxJump) { scrollDelta = daBottom - screenBottom; } } if (scrollDelta == 0) { return false; } int i; if (direction == 130) { i = scrollDelta; } else { i = -scrollDelta; } doScrollY(i); } else { nextFocused.getDrawingRect(this.mTempRect); offsetDescendantRectToMyCoords(nextFocused, this.mTempRect); doScrollY(computeScrollDeltaToGetChildRectOnScreen(this.mTempRect)); nextFocused.requestFocus(direction); } if (currentFocused != null && currentFocused.isFocused() && isOffScreen(currentFocused)) { int descendantFocusability = getDescendantFocusability(); setDescendantFocusability(131072); requestFocus(); setDescendantFocusability(descendantFocusability); } return true; }
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; }
/** * You can call this function yourself to have the scroll view perform * scrolling from a key event, just as if the event had been dispatched to * it by the view hierarchy. * * @param event The key event to execute. * @return Return true if the event was handled, else false. */ public boolean executeKeyEvent(KeyEvent event) { mTempRect.setEmpty(); if (!canScroll()) { if (isFocused()) { View currentFocused = findFocus(); if (currentFocused == this) currentFocused = null; View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, View.FOCUS_DOWN); return nextFocused != null && nextFocused != this && nextFocused.requestFocus(View.FOCUS_DOWN); } return false; } boolean handled = false; if (event.getAction() == KeyEvent.ACTION_DOWN) { switch (event.getKeyCode()) { case KeyEvent.KEYCODE_DPAD_UP: if (!event.isAltPressed()) { handled = arrowScroll(View.FOCUS_UP, false); } else { handled = fullScroll(View.FOCUS_UP, false); } break; case KeyEvent.KEYCODE_DPAD_DOWN: if (!event.isAltPressed()) { handled = arrowScroll(View.FOCUS_DOWN, false); } else { handled = fullScroll(View.FOCUS_DOWN, false); } break; case KeyEvent.KEYCODE_DPAD_LEFT: if (!event.isAltPressed()) { handled = arrowScroll(View.FOCUS_LEFT, true); } else { handled = fullScroll(View.FOCUS_LEFT, true); } break; case KeyEvent.KEYCODE_DPAD_RIGHT: if (!event.isAltPressed()) { handled = arrowScroll(View.FOCUS_RIGHT, true); } else { handled = fullScroll(View.FOCUS_RIGHT, true); } break; } } return handled; }