Android キーボードを閉じる処理について

Android

外側のViewをタップしてキーボードを閉じるオーソドックスな方法として、onTouchEventをオーバーライドして、その中にキーボードを閉じる処理を実装をする方法がある。
よく使う実装の割に都度調べてたり、一筋縄でいかないこともあったのでそれぞれ忘れないようにメモします。

まずはよく使うオーソドックスな実装方法。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mainLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
 
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
 
</LinearLayout>
public class MainActivity extends Activity {
 
    private InputMethodManager mInputMethodManager;
    private LinearLayout mMainLayout;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        EditText editText = (EditText) findViewById(R.id.editText);
        mMainLayout = (LinearLayout)findViewById(R.id.mainLayout);
        mInputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    }
 
    /**
    * EditText編集時に背景をタップしたら呼ばれる
    */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
         //キーボードを隠す
         mInputMethodManager.hideSoftInputFromWindow(mMainLayout.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
         //背景にフォーカスを移す
         mMainLayout.requestFocus();
         return false;
    }
}

これで大体は問題なし。

しかし、どうやらViewの構成やリスナーの実装箇所によってonTouchEventがよばれないみたいです。
そんな時は、代わりにdispatchTouchEventをオーバーライドしてあげましょう。

@Override
/**
* onTouchEventの前に呼ばれる
*/
public boolean dispatchTouchEvent(MotionEvent ev) {
    //キーボードを隠す
    inputMethodManager.hideSoftInputFromWindow(mainLayout.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    //背景にフォーカスを移す
    mainLayout.requestFocus();
    return super.dispatchTouchEvent(ev);
}

onTouchEventが呼ばれる前にdispatchTouchEventが呼ばれるため、dispatchTouchEventをオーバライドしてタップ時の処理を実装してあげればよいでしょう。

Viewの構成やリスナーの実装箇所によってタッチイベンの連鎖が途中で止まってしまい、onTouchEventまで伝達されない模様。

タッチイベントの詳細は以下サイトに詳しく記述されてます。

Android のタッチイベントを理解する(その1) - Unmotivated
タッチイベントがうまく流れてこなくて困ったり、自力でイベントをルーティングしたりするときに困ったりと、ちょこちょことタッチイベントについて勉強したのでまとめておきます。 主にタッチイベントがどう流れてどう止まるかなどについて調べています。 …

コピペもいいけど、たまにはちゃんと、仕組みを理解することを心がけよう!と思った今日この頃でした。

タイトルとURLをコピーしました