Android中EditText焦點(diǎn)問(wèn)題

最近在項(xiàng)目中碰到EditText的焦點(diǎn)問(wèn)題,特此記錄下,以便遇到相同問(wèn)題的朋友參考。

問(wèn)題:當(dāng)EditText失去焦點(diǎn)時(shí)做內(nèi)容校驗(yàn)

場(chǎng)景:用戶編輯EditText將內(nèi)容清空,當(dāng)點(diǎn)擊空白地方時(shí)關(guān)閉軟鍵盤(pán),同時(shí)校驗(yàn)EditText的內(nèi)容,如果為空則設(shè)為"1"。
問(wèn)題遠(yuǎn)沒(méi)有看著那么簡(jiǎn)單哦

第一步:添加焦點(diǎn)監(jiān)聽(tīng)
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");
                }
            }
        });
第二步:點(diǎn)擊空白地方時(shí)關(guān)閉軟鍵盤(pán)

在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);
        }
        // 必不可少,否則所有的組件都不會(huì)有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};
            //獲取輸入框當(dāng)前的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) {
                // 點(diǎn)擊的是輸入框區(qū)域,保留點(diǎn)擊EditText的事件
                return false;
            } else {
                //使EditText觸發(fā)一次失去焦點(diǎn)事件
                v.setFocusable(false);
//                v.setFocusable(true); //這里不需要是因?yàn)橄旅嬉痪浯a會(huì)同時(shí)實(shí)現(xiàn)這個(gè)功能
                v.setFocusableInTouchMode(true);
                return true;
            }
        }
        return false;
    }

加入以上代碼你驚喜的發(fā)現(xiàn)問(wèn)題貌似完美的解決了。但是,如果你的界面中有多個(gè)EditText,你會(huì)發(fā)現(xiàn)當(dāng)點(diǎn)擊第一個(gè)EditText時(shí),第二個(gè)EditText會(huì)有光標(biāo)閃以下,或者點(diǎn)擊第二個(gè)或者之后的EditText,第一個(gè)EditText會(huì)有光標(biāo)閃一下。通過(guò)Log你會(huì)發(fā)現(xiàn)從第二次點(diǎn)擊EditText起,每次點(diǎn)擊EditText都會(huì)先觸發(fā)一次失去焦點(diǎn),再觸發(fā)一次獲取焦點(diǎn)。由此可以推斷當(dāng)存在多個(gè)EditText時(shí),一個(gè)EditText失去焦點(diǎn)會(huì)觸發(fā)另一個(gè)獲取焦點(diǎn)。這問(wèn)題必須解決,而且出現(xiàn)屏幕光標(biāo)閃動(dòng)影響用戶體驗(yàn)。

第三步:避免另一個(gè)EditText獲取焦點(diǎn)

解決這個(gè)問(wèn)題的做法是在同一個(gè)XML中將一個(gè)不會(huì)有響應(yīng)的控件(如TextView)設(shè)置如下屬性:

android:focusable="true"
android:focusableInTouchMode="true"

問(wèn)題完美解決。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容