下面列出了android.view.View#FOCUS_BACKWARD 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void onTakeFocus(TextView widget, Spannable text, int dir) {
Layout layout = widget.getLayout();
if (layout != null && (dir & View.FOCUS_FORWARD) != 0) {
widget.scrollTo(widget.getScrollX(),
layout.getLineTop(0));
}
if (layout != null && (dir & View.FOCUS_BACKWARD) != 0) {
int padding = widget.getTotalPaddingTop() +
widget.getTotalPaddingBottom();
int line = layout.getLineCount() - 1;
widget.scrollTo(widget.getScrollX(),
layout.getLineTop(line+1) -
(widget.getHeight() - padding));
}
}
/**
* 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.
* <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);
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 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 void onTakeFocus(TextView view, Spannable text, int dir) {
Selection.removeSelection(text);
if ((dir & View.FOCUS_BACKWARD) != 0) {
text.setSpan(FROM_BELOW, 0, 0, Spannable.SPAN_POINT_POINT);
} else {
text.removeSpan(FROM_BELOW);
}
}
/**
* 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;
}
}
/**
* 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 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;
}
}
/**
* 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 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 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;
}
}
@Override
public void onTakeFocus(@NonNull TextView view, Spannable text, int dir) {
Selection.removeSelection(text);
if ((dir & View.FOCUS_BACKWARD) != 0) {
text.setSpan(FROM_BELOW, 0, 0, Spannable.SPAN_POINT_POINT);
} else {
text.removeSpan(FROM_BELOW);
}
}
/**
* 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);
}
@Override
public void onTakeFocus(TextView view, Spannable text, int dir) {
Selection.removeSelection(text);
if ((dir & View.FOCUS_BACKWARD) != 0) {
text.setSpan(FROM_BELOW, 0, 0, Spannable.SPAN_POINT_POINT);
} else {
text.removeSpan(FROM_BELOW);
}
}
@Override
public View focusSearch(int direction) {
if (direction == View.FOCUS_BACKWARD
&& mUrlBarDelegate.getCurrentTab().getView() != null) {
return mUrlBarDelegate.getCurrentTab().getView();
} else {
return super.focusSearch(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 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;
}
}
@Override
public void onTakeFocus(TextView view, Spannable text, int dir) {
Selection.removeSelection(text);
if ((dir & View.FOCUS_BACKWARD) != 0) {
text.setSpan(FROM_BELOW, 0, 0, Spannable.SPAN_POINT_POINT);
} else {
text.removeSpan(FROM_BELOW);
}
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
// Handle automatic focus changes.
if (event.getAction() == KeyEvent.ACTION_DOWN) {
int direction = 0;
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_DPAD_LEFT:
if (event.hasNoModifiers()) {
direction = View.FOCUS_LEFT;
}
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (event.hasNoModifiers()) {
direction = View.FOCUS_RIGHT;
}
break;
case KeyEvent.KEYCODE_DPAD_UP:
if (event.hasNoModifiers()) {
direction = View.FOCUS_UP;
}
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
if (event.hasNoModifiers()) {
direction = View.FOCUS_DOWN;
}
break;
case KeyEvent.KEYCODE_TAB:
if (event.hasNoModifiers()) {
direction = View.FOCUS_FORWARD;
} else if (event.hasModifiers(KeyEvent.META_SHIFT_ON)) {
direction = View.FOCUS_BACKWARD;
}
break;
}
if (direction == View.FOCUS_DOWN || direction == View.FOCUS_UP) {
View focused = findFocus();
if (focused != null) {
View v = focused.focusSearch(direction);
if (v == null) {
Utils.playKeySound(this, Utils.SOUND_ERROR_KEY);
mMetroCursorView.showIndicator();
}
}
}
}
boolean ret = super.dispatchKeyEvent(event);
return ret;
}
@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;
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// We need to handle focus change within the SimpleMonthView because we are simulating
// multiple Views. The arrow keys will move between days until there is no space (no
// day to the left, top, right, or bottom). Focus forward and back jumps out of the
// SimpleMonthView, skipping over other SimpleMonthViews in the parent ViewPager
// to the next focusable View in the hierarchy.
boolean focusChanged = false;
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_DPAD_LEFT:
if (event.hasNoModifiers()) {
focusChanged = moveOneDay(isLayoutRtl());
}
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (event.hasNoModifiers()) {
focusChanged = moveOneDay(!isLayoutRtl());
}
break;
case KeyEvent.KEYCODE_DPAD_UP:
if (event.hasNoModifiers()) {
ensureFocusedDay();
if (mHighlightedDay > 7) {
mHighlightedDay -= 7;
focusChanged = true;
}
}
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
if (event.hasNoModifiers()) {
ensureFocusedDay();
if (mHighlightedDay <= mDaysInMonth - 7) {
mHighlightedDay += 7;
focusChanged = true;
}
}
break;
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
if (mHighlightedDay != -1) {
onDayClicked(mHighlightedDay);
return true;
}
break;
case KeyEvent.KEYCODE_TAB: {
int focusChangeDirection = 0;
if (event.hasNoModifiers()) {
focusChangeDirection = View.FOCUS_FORWARD;
} else if (event.hasModifiers(KeyEvent.META_SHIFT_ON)) {
focusChangeDirection = View.FOCUS_BACKWARD;
}
if (focusChangeDirection != 0) {
final ViewParent parent = getParent();
// move out of the ViewPager next/previous
View nextFocus = this;
do {
nextFocus = nextFocus.focusSearch(focusChangeDirection);
} while (nextFocus != null && nextFocus != this &&
nextFocus.getParent() == parent);
if (nextFocus != null) {
nextFocus.requestFocus();
return true;
}
}
break;
}
}
if (focusChanged) {
invalidate();
return true;
} else {
return super.onKeyDown(keyCode, event);
}
}