Android の EditText の IME を制御する(2)

前回は、IME を制御するメソッドを作成した。今回は、EditText にフォーカスがあるかないかで IME の表示を制御してみる。目標は、

  • EditText がフォーカスを得ると IME が起動
  • EditText 以外の箇所をタップすると IME が終了

という動作だ。

普通にコーディングしただけだと、EditText 以外の箇所をタップしても IME が消えないことがあったので、少し強引なコードを用意してみた。以下のコードは、Context と EditText を引数として渡すことを前提にしている。showInputMethodEditor や hideInputMethodEditor は、前回作成したメソッドだ。

public static void inputMethodEditorControl(final Context context,
        final View view) {

    // EditText をタップしたらフォーカスを持つようにする
    view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!view.hasFocus()) {
                view.setFocusable(true);
                view.setFocusableInTouchMode(true);
                view.requestFocus();
            }
        }
    });
    
    // EditText のフォーカスの変化に応じて IME を制御
    final View.OnFocusChangeListener listener = view
            .getOnFocusChangeListener();
    view.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            // フォーカスを持ったら表示
            if (hasFocus) {
                showInputMethodEditor(context, view);
            }
            // フォーカスを失ったら非表示に
            else {
                hideInputMethodEditor(context, view);
            }
            if (null != listener) {
                listener.onFocusChange(v, hasFocus);
            }
        }
    });

    // EditText の上位の View がクリックされたら EditText のフォーカスを外す
    ViewParent parent = view.getParent();
    while (parent instanceof View) {
        View v = (View) parent;
        v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                for (final View view : views) {
                    view.setFocusable(false);
                    view.setFocusableInTouchMode(false);
                    view.clearFocus();
                }
            }
        });
        parent = v.getParent();
    }
}

コードの内容は、コメントを追加して説明してみた。最後の「EditText の上位の View がクリックされたら EditText のフォーカスを外す」の処理は、EditText の上位の View をたどっていって、どれかがタップされたら EditText をフォーカスできないように変更している。ただ、こんな処理が本当に必要なのか疑問だ。わざわざ View の階層をたどって処理を追加していかなければならないとしたら、結構面倒だ。何か間違えているか、勘違いしているか・・・設定を忘れているような気がするが、とりあえず動いているので使ってみている(もっとも、実際のコードは少し違うが)。よい方法が見つかったら、「Android の EditText の IME を制御する(3)」で報告したい。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Time limit is exhausted. Please reload CAPTCHA.