安卓開發 點選空白處收起鍵盤

pswyjz發表於2021-09-09

前言

在產品迭代的過程中,為了最佳化使用者體驗,展示我們產品的人文情懷,在有EditText控制元件或者自定義的輸入框控制元件的頁面,我們時常會被要求加入點選非輸入框區域收起鍵盤的操作。下面我們來了解一下這個功能的實現。

正文

其實看到這個需求第一個想到的方法就是為其他控制元件setTouchListener,但是很顯然這是個相當笨拙且會造成大量冗餘程式碼的操作而且時間成本也相對較大,所以捨棄。這裡我們最靠譜的做法還是基於Android的事件分發機制。對於事件分發機制不再贅述,感興趣的請自行搜尋。
前面說到產品迭代,其實無論是產品剛開始還是已經在迭代,程式碼的複用性都是我們應該考慮到的,以下程式碼均實現在基類BaseActivity中
首先我們要重寫dispatchTouchEvent()把操作放在使用者點選的時候

/**
     * 點選空白區域隱藏鍵盤.
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent me) {        if (me.getAction() == MotionEvent.ACTION_DOWN) {  //把操作放在使用者點選的時候
            View v = getCurrentFocus();      //得到當前頁面的焦點,ps:有輸入框的頁面焦點一般會被輸入框佔據
            if (isShouldHideKeyboard(v, me)) { //判斷使用者點選的是否是輸入框以外的區域
                hideKeyboard(v.getWindowToken());   //收起鍵盤
            }
        }        return super.dispatchTouchEvent(ev);
    }

重點來了,識別使用者點選的區域

 /**
     * 根據EditText所在座標和使用者點選的座標相對比,來判斷是否隱藏鍵盤,因為當使用者點選EditText時則不能隱藏
     *
     * @param v
     * @param event
     * @return
     */
    private boolean isShouldHideKeyboard(View v, MotionEvent event) {        if (v != null && (v instanceof EditText)) {  //判斷得到的焦點控制元件是否包含EditText
            int[] l = {0, 0};
            v.getLocationInWindow(l);            int left = l[0],    //得到輸入框在螢幕中上下左右的位置
                    top = l[1],
                    bottom = top + v.getHeight(),
                    right = left + v.getWidth();            if (event.getX() > left && event.getX()  top && event.getY() 

最後一步,收起鍵盤

/**
     * 獲取InputMethodManager,隱藏軟鍵盤
     * @param token
     */
    private void hideKeyboard(IBinder token) {        if (token != null) {
            InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            im.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }

OK,這樣繼承基類BaseActivity的左右有輸出框並且使用系統預設鍵盤的頁面就都實現了功能。


接下來我們看看自定義安全鍵盤如何來實現這個需求,自定義安全鍵盤的實現請看我寫的這篇。
很簡單我們在識別使用者點選區域的地方加一點小動作,獲取自定義鍵盤的在螢幕中上下左右的區域

            int[] y = {0, 0};
            ll_jianpan.getLocationInWindow(y);            int left1 = y[0],
                    top1 = y[1],
                    bottom1 = top1 + ll_jianpan.getHeight(),
                    right1 = left1 + ll_jianpan.getWidth();

在判斷區域的時候新加條件

if ((event.getX() > left && event.getX()  top && event.getY()  left1 && event.getX()  top1 && event.getY() 

當然如果想讓某個指定的view點選不使鍵盤消失也可以這樣操作。

後記

明明是個程式猿卻喜歡優美的文字,從今天開始,每篇最後分享句子吧。

當我吃東西時,就只管吃;當我走路時,就只管走。
因為我既不生活在過去,也不生活在未來,我只有現在,它才是我感興趣的。
如果你能永遠停留在現在,那你將是最幸福的人。生活就是一個節日,是一場盛大的慶典。因為生活永遠是,也僅僅是我們現在經歷的這一刻。
—保羅柯艾《牧羊少年奇幻之旅》



作者:AirrWang
連結:
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/755/viewspace-2809289/,如需轉載,請註明出處,否則將追究法律責任。

相關文章