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>

Javaコード

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 のタッチイベントを理解する

いやー、奥が深いですねー(^^;
広告

Profile