最近在項目中碰到EditText的焦點問題,特此記錄下鸽捻,以便遇到相同問題的朋友參考御板。
問題:當EditText失去焦點時做內(nèi)容校驗
場景:用戶編輯EditText
將內(nèi)容清空,當點擊空白地方時關閉軟鍵盤渔隶,同時校驗EditText
的內(nèi)容,如果為空則設為"1"洁奈。
問題遠沒有看著那么簡單哦
第一步:添加焦點監(jiān)聽
view.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus){
Log.d("Tag","lose focus");
if(TextUtils.isEmpty(((EditText)v).getText().toString().trim())){
view.setText("1");
}
}else {
Log.d("Tag","get focus");
}
}
});
第二步:點擊空白地方時關閉軟鍵盤
在Activity中使用以下代碼:
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
View v = getCurrentFocus();
if (isShouldHideInput(v, ev)) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
return super.dispatchTouchEvent(ev);
}
// 必不可少间唉,否則所有的組件都不會有TouchEvent了
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}
public boolean isShouldHideInput(View v, MotionEvent event) {
if (v != null && (v instanceof EditText)) {
int[] leftTop = {0, 0};
//獲取輸入框當前的location位置
v.getLocationInWindow(leftTop);
int left = leftTop[0];
int top = leftTop[1];
int bottom = top + v.getHeight();
int right = left + v.getWidth();
if (event.getX() > left && event.getX() < right
&& event.getY() > top && event.getY() < bottom) {
// 點擊的是輸入框區(qū)域,保留點擊EditText的事件
return false;
} else {
//使EditText觸發(fā)一次失去焦點事件
v.setFocusable(false);
// v.setFocusable(true); //這里不需要是因為下面一句代碼會同時實現(xiàn)這個功能
v.setFocusableInTouchMode(true);
return true;
}
}
return false;
}
加入以上代碼你驚喜的發(fā)現(xiàn)問題貌似完美的解決了利术。但是终吼,如果你的界面中有多個EditText
,你會發(fā)現(xiàn)當點擊第一個EditText
時,第二個EditText
會有光標閃以下氯哮,或者點擊第二個或者之后的EditText
,第一個EditText
會有光標閃一下际跪。通過Log你會發(fā)現(xiàn)從第二次點擊EditText
起商佛,每次點擊EditText
都會先觸發(fā)一次失去焦點,再觸發(fā)一次獲取焦點姆打。由此可以推斷當存在多個EditText
時良姆,一個EditText
失去焦點會觸發(fā)另一個獲取焦點。這問題必須解決幔戏,而且出現(xiàn)屏幕光標閃動影響用戶體驗玛追。
第三步:避免另一個EditText獲取焦點
解決這個問題的做法是在同一個XML中將一個不會有響應的控件(如TextView
)設置如下屬性:
android:focusable="true"
android:focusableInTouchMode="true"
問題完美解決。