Android点击前一个焦点之外的地方使之失去焦点并隐藏软键盘
package matroleox.bscalculator;
import android.app.Activity;
import android.content.Context;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
public class FocusCleaner {
private View previousFocus;
/**
* the default is to hide softKeyboard.
* @see #cleanFocus(Activity, MotionEvent, boolean)
* */
public void cleanFocus(Activity activity, MotionEvent currentMotionEvent) {
cleanFocus(activity, currentMotionEvent, true);
}
/**
* The method must be put in the method dispatchTouchEvent of an Activity
* and the method dispatchTouchEvent must call super.dispatchTouchEvent(ev) at its first line.
* For example
* public boolean dispatchTouchEvent(MotionEvent ev) {
* boolean isConsumed = super.dispatchTouchEvent(ev);
* focusCleaner.cleanFocus(this, ev);
* return isConsumed;
* }
* */
public void cleanFocus(Activity activity, MotionEvent currentMotionEvent, boolean hideSoftKeyboard) {
final int action = currentMotionEvent.getAction();
if (action == MotionEvent.ACTION_DOWN) {
previousFocus = activity.getCurrentFocus();
if (isOutsidePreviousFocus(previousFocus, currentMotionEvent)) previousFocus.clearFocus();
} else if (hideSoftKeyboard
&& action == MotionEvent.ACTION_UP
&& activity.getCurrentFocus() == null
) {
hideSoftKeyboard(previousFocus, activity);
}
}
private boolean isOutsidePreviousFocus(View previousFocus, MotionEvent currentMotionEvent) {
if (previousFocus == null) return false;
final int X = 0;
final int Y = 1;
final int[] previousFocusStart = new int[2];
previousFocus.getLocationInWindow(previousFocusStart);
final int[] previousFocusEnd = new int[2];
previousFocusEnd[X] = previousFocusStart[X] + previousFocus.getWidth();
previousFocusEnd[Y] = previousFocusStart[Y] + previousFocus.getHeight();
final float currentTouchX = currentMotionEvent.getX();
final float currentTouchY = currentMotionEvent.getY();
return !(currentTouchX > previousFocusStart[X]
&& currentTouchX < previousFocusEnd[X]
&& currentTouchY > previousFocusStart[Y]
&& currentTouchY < previousFocusEnd[Y]);
}
private void hideSoftKeyboard(View v, Activity activity) {
if (v == null) return;
InputMethodManager im =
(InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
if(im != null) im.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
down 中是之前的焦点
up 中是当前焦点
使用
在Activity中重写dispatchTouchEvent
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean isConsumed = super.dispatchTouchEvent(ev);
focusCleaner.cleanFocus(this, ev);
return isConsumed;
}