下面列出了android.view.View#hasFocus ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public OnTouchListener getOnTouchListener() {
return new OnTouchListener() {
private Map<Integer, Integer> finger2pitch = new HashMap<Integer, Integer>();
public boolean onTouch(View v, MotionEvent e) {
if (!v.hasFocus()) v.requestFocus();
if (autoPlay || h.done || h.score.gameOver) return false;
int pitch;
// Use old, non-multi-touch-supporting SDK 3/4 methods
int actionpid = e.getAction() >> 8;
switch(e.getAction()) {
case MotionEvent.ACTION_DOWN:
actionpid = 0;
pitch = h.onTouch_Down(e.getX(), e.getY());
if (pitch > 0) finger2pitch.put(actionpid, pitch);
return pitch > 0;
case MotionEvent.ACTION_UP:
h.onTouch_Up(e.getX(actionpid), e.getY(actionpid));
return h.onTouch_Up(finger2pitch.get(actionpid));
default:
return false;
}
}
};
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(@Nullable View view, @NonNull MotionEvent arg1) {
if (view == null)
return false;
if (!view.hasFocus()) {
view.requestFocus();
}
mAction = arg1.getAction();
mY = arg1.getY();
if (mAction == MotionEvent.ACTION_DOWN) {
mLocation = mY;
} else if (mAction == MotionEvent.ACTION_UP) {
final float distance = (mY - mLocation);
if (distance > SCROLL_UP_THRESHOLD && view.getScrollY() < SCROLL_UP_THRESHOLD) {
mUIController.showActionBar();
} else if (distance < -SCROLL_UP_THRESHOLD) {
mUIController.hideActionBar();
}
mLocation = 0;
}
mGestureDetector.onTouchEvent(arg1);
return false;
}
private boolean tryPassFirstViewToPrevious(DocumentPage current, DocumentPage previous) {
final View view = current.getViewCount() == 0 ? null : current.getViewAt(0);
if (view != null && previous.canTake(view, view.getLayoutParams(), false)) {
LOG.i("tryPassFirstViewToPrevious:", "passing view", Utils.mark(view),
"from", current.getNumber(), "to", previous.getNumber());
boolean hasFocus = view.hasFocus();
current.release(view);
previous.take(view, view.getLayoutParams());
if (current.getViewCount() == 0) {
onEmpty(current);
}
if (hasFocus) {
view.post(new Runnable() {
@Override
public void run() {
view.requestFocus();
Utils.showKeyboard(view);
}
});
}
return true;
}
return false;
}
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}");
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(@Nullable View view, @NonNull MotionEvent arg1) {
if (view == null)
return false;
if (!view.hasFocus()) {
view.requestFocus();
}
mAction = arg1.getAction();
mY = arg1.getY();
if (mAction == MotionEvent.ACTION_DOWN) {
mLocation = mY;
} else if (mAction == MotionEvent.ACTION_UP) {
final float distance = (mY - mLocation);
if (distance > SCROLL_UP_THRESHOLD && view.getScrollY() < SCROLL_UP_THRESHOLD) {
mUIController.showActionBar();
} else if (distance < -SCROLL_UP_THRESHOLD) {
mUIController.hideActionBar();
}
mLocation = 0;
}
mGestureDetector.onTouchEvent(arg1);
return false;
}
/**
* In layout, if there is a view that needs to get focus,
* make sure the view is displayed.
*/
private void scrollToFocusViewInLayout() {
if (hasFocus() && !isSmoothScrolling() && mFocusPosition != NO_POSITION) {
View focusView = findViewByPosition(mFocusPosition);
if (focusView != null) {
if (getScrollPosition(focusView, mTwoInts)) {
int maxScrollDistance = getMaxScrollDistance();
int scrollDistance = mTwoInts[0];
if (scrollDistance > 0) {
if (mHorizontalOffset + scrollDistance > maxScrollDistance) {
scrollDistance = maxScrollDistance - mHorizontalOffset;
}
offsetChildrenPrimary(-scrollDistance);
}
if (!focusView.hasFocus()) {
focusView.requestFocus();
dispatchChildSelected();
}
}
} else if (mFocusPosition != NO_POSITION){
scrollToSelection(mBaseRecyclerView, mFocusPosition, mSubFocusPosition, true,
mPrimaryScrollExtra);
}
}
}
public void setCurrentTabToFocusedTab() {
View tab = null;
int index = -1;
final int count = getTabCount();
for (int i = 0; i < count; ++i) {
View v = getChildTabViewAt(i);
if (v.hasFocus()) {
tab = v;
index = i;
break;
}
}
if (index > -1) {
super.setCurrentTab(index);
super.onFocusChange(tab, true);
}
}
public void setCurrentTabToFocusedTab() {
View tab = null;
int index = -1;
final int count = getTabCount();
for (int i = 0; i < count; ++i) {
View v = getChildTabViewAt(i);
if (v.hasFocus()) {
tab = v;
index = i;
break;
}
}
if (index > -1) {
super.setCurrentTab(index);
super.onFocusChange(tab, true);
}
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
switch (v.getId()) {
case R.id.etEmail:
if (!v.hasFocus()) {
validateEmail();
}
break;
case R.id.etPassword:
if (!v.hasFocus()) {
validatePassword();
}
break;
}
}
/**
* 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_LEFT && direction != View.FOCUS_RIGHT ) {
throw new IllegalArgumentException( "direction must be one of"
+ " {View.FOCUS_LEFT, View.FOCUS_RIGHT}" );
}
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 OnTouchListener getOnTouchListener() {
return new OnTouchListener() {
private Map<Integer, Integer> finger2pitch = new HashMap<Integer, Integer>();
public boolean onTouch(View v, MotionEvent e) {
if (!v.hasFocus()) v.requestFocus();
if (autoPlay || h.done || h.score.gameOver) return false;
int pitch;
// Normal multi-touch
int actionmask = e.getAction() & MotionEvent.ACTION_MASK;
@SuppressWarnings("deprecation")
int actionpid = e.getAction() >> MotionEvent.ACTION_POINTER_ID_SHIFT;
switch (actionmask) {
case MotionEvent.ACTION_DOWN:
actionpid = 0;
//fallthru
case MotionEvent.ACTION_POINTER_DOWN:
pitch = h.onTouch_Down(e.getX(actionpid), e.getY(actionpid));
if (pitch > 0) finger2pitch.put(actionpid, pitch);
return pitch > 0;
case MotionEvent.ACTION_POINTER_UP:
h.onTouch_Up(e.getX(actionpid), e.getY(actionpid));
if (finger2pitch.containsKey(actionpid)) {
return h.onTouch_Up(finger2pitch.get(actionpid));
} else {
return h.onTouch_Up(0xF);
}
case MotionEvent.ACTION_UP:
h.onTouch_Up(e.getX(actionpid), e.getY(actionpid));
return h.onTouch_Up(0xF);
default:
return false;
}
}
};
}
private View getFocusedLeafChild(View root) {
if (root instanceof NumberPicker) {
return root.hasFocus() ? root : null;
}
if (root instanceof ViewGroup) {
ViewGroup parent = (ViewGroup) root;
return getFocusedLeafChild(parent.getFocusedChild());
}
return null;
}
@DatabindingMethod
public void onClickChanageFocus(View v){
if(v.hasFocus()){
ViewUtil.loseFocus(v);
}else {
ViewUtil.obtainFocus(v);
}
}
/**
* 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) {
if (direction != View.FOCUS_LEFT && direction != View.FOCUS_RIGHT) {
throw new IllegalArgumentException("direction must be one of"
+ " {View.FOCUS_LEFT, View.FOCUS_RIGHT}");
}
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
Rect focusedRect = mTempRect;
if (currentFocus != null) {
currentFocus.getFocusedRect(focusedRect);
offsetDescendantRectToMyCoords(currentFocus, focusedRect);
offsetRectIntoDescendantCoords(nextFocus, focusedRect);
} else {
focusedRect = null;
}
if (nextFocus.requestFocus(direction, focusedRect)) {
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;
}
@Override
public void onSpaceOver(DocumentColumn column) {
// This child was not OK in the column it came from.
// If this is called, we are probably wrap content.
if (column.getViewCount() == 0) return; // <- happens during collects..
mLog.i("onSpaceOver:", "triggered by column", column.getNumber());
int which = mColumns.indexOf(column);
boolean last = which == mColumnCount - 1;
if (last) {
// This is not our business.
mLog.i("onSpaceOver:", "last column, passing up to pager.");
getRoot().onSpaceOver(this);
} else {
final View lastView = column.getViewAt(column.getViewCount() - 1);
// If it is marked as untakable, there is nothing we can do.
// But it could be a view that just grew to be untakable, so we check if the column
// could take it if it were empty.
if (Utils.isUntakable(lastView)) return;
if (!column.canTake(lastView, lastView.getLayoutParams(), true)) {
Utils.setUntakable(lastView, true);
return;
}
DocumentColumn next = mColumns.get(which + 1);
mLog.i("onSpaceOver:", "passing view", Utils.mark(lastView), "to column", next.getNumber());
boolean hasFocus = lastView.hasFocus();
column.release(lastView);
next.takeFirst(lastView, lastView.getLayoutParams());
if (hasFocus) {
lastView.post(new Runnable() {
@Override
public void run() {
lastView.requestFocus();
Utils.showKeyboard(lastView);
}
});
}
}
}
@Override
public void onSpaceOver(DocumentPage page) {
// This child was not OK in the page it came from. Can we open a new one?
// If this is called, we are NOT wrap content.
if (!mEnabled) return;
LOG.i("onSpaceOver:", "triggered by page", page.getNumber());
final View last = page.getViewAt(page.getViewCount() - 1);
// If it is marked as untakable, there is nothing we can do.
// But it could be a view that just grew to be untakable, so we check if the page
// could take it if it were empty.
if (Utils.isUntakable(last)) return;
if (!page.canTake(last, last.getLayoutParams(), true)) {
Utils.setUntakable(last, true);
return;
}
// Pass to a new page.
LOG.i("onSpaceOver:", "passing view", Utils.mark(last),
"to page", page.getNumber() + 1);
synchronized (mLock) {
DocumentPage next;
int which = mPages.indexOf(page);
int other = which + 1;
if (other <= getPageCount() - 1) {
next = mPages.get(which + 1);
} else {
openPage();
next = getLastPage();
}
boolean hasFocus = last.hasFocus();
page.release(last);
next.takeFirst(last, last.getLayoutParams());
if (hasFocus) {
last.post(new Runnable() {
@Override
public void run() {
last.requestFocus();
Utils.showKeyboard(last);
}
});
}
}
}
private boolean arrowScrollImpl(int direction) {
if (getChildCount() <= 0) {
return false;
}
boolean needToRedraw;
View focused;
View selectedView = getSelectedView();
int selectedPos = this.mSelectedPosition;
int nextSelectedPosition = lookForSelectablePositionOnScreen(direction);
int amountToScroll = amountToScroll(direction, nextSelectedPosition);
ArrowScrollFocusResult focusResult = this.mItemsCanFocus ? arrowScrollFocused(direction) : null;
if (focusResult != null) {
nextSelectedPosition = focusResult.getSelectedPosition();
amountToScroll = focusResult.getAmountToScroll();
}
if (focusResult != null) {
needToRedraw = true;
} else {
needToRedraw = false;
}
if (nextSelectedPosition != -1) {
boolean z;
if (focusResult != null) {
z = true;
} else {
z = false;
}
handleNewSelectionChange(selectedView, direction, nextSelectedPosition, z);
setSelectedPositionInt(nextSelectedPosition);
setNextSelectedPositionInt(nextSelectedPosition);
selectedView = getSelectedView();
selectedPos = nextSelectedPosition;
if (this.mItemsCanFocus && focusResult == null) {
focused = getFocusedChild();
if (focused != null) {
focused.clearFocus();
}
}
needToRedraw = true;
checkSelectionChanged();
}
if (amountToScroll > 0) {
if (direction != 33) {
amountToScroll = -amountToScroll;
}
scrollListItemsBy(amountToScroll);
needToRedraw = true;
}
if (this.mItemsCanFocus && focusResult == null && selectedView != null && selectedView.hasFocus()) {
focused = selectedView.findFocus();
if (!isViewAncestorOf(focused, this) || distanceToView(focused) > 0) {
focused.clearFocus();
}
}
if (!(nextSelectedPosition != -1 || selectedView == null || isViewAncestorOf(selectedView, this))) {
selectedView = null;
hideSelector();
this.mResurrectToPosition = -1;
}
if (!needToRedraw) {
return false;
}
if (selectedView != null) {
positionSelector(selectedPos, selectedView);
this.mSelectedLeft = selectedView.getLeft();
}
if (!awakenScrollBars()) {
invalidate();
}
invokeOnItemScrollListener();
return true;
}
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;
}
@Override
public boolean matchesSafely(View view) {
return view.hasFocus() == hasFocus;
}
/**
* @return {@code true} if the given view has a focus.
*/
public static boolean hasFocus(View view) {
// If the container view is not focusable, we consider it always focused from
// Chromium's point of view.
return !view.isFocusable() ? true : view.hasFocus();
}