LoginSignup
8
9

More than 5 years have passed since last update.

【Android】「EditTextを複数配置した画面」を起動時に「特定のEditText」にフォーカスを設定する方法

Last updated at Posted at 2017-11-12

お任せで良ければ便利なフォーカス仕様なのだが……

EditTextを複数配置した画面」構成では、画面(Activity)起動時、「最初に検出したEditText」に対してシステムは勝手にフォーカスを当ててくれる。

「入力フォーマット画面(アカウントのログイン画面とか)」などを作成時は、これはとても有難い仕様だ、フォーカスのことまで考えなくて済むのでね!

だが、、、

画面起動時、例えば、以下メモ帳アプリのスクショのように、上段のEditText(タイトルを入力...となっている部分)にはフォーカスを当てずに、下段のEditTextにまず最初にフォーカスを当てたい、ということがあった場合は、策を練らなければならない。

Screenshot_2017-11-12-20-51-01.png

このメモ帳アプリの例だと、上段が「Toolbarに配置したEditText」で、下段が「メモ入力欄としてのEditText」。

画面起動時、システムに任せたままにすると、上段の「Toolbarに配置したEditText」にフォーカスが当たってしまう

例えば、これはよく見掛けるケースだが、「EditTextが画面にひとつしか配置されていない画面」の場合は、他のViewに対して「android:focusable="true"」を設定することで、初期フォーカスをEditTextに当てないという方法も選択できるのだが、本記事のケースでは、EditTextに対して以下は意味がない。

    <EditText
        android:id="@+id/toolbar_title" />

    <EditText
        android:id="@+id/note_edit_body"
        android:focusable="true"
        android:focusableInTouchMode="true" />

これでは、「上段のEditText(@+id/toolbar_title)」にフォーカスが当たったままで、解決できない。

では、どうしようか?

サンプルコード

逆転の発想で、初期フォーカスを当てたくないEditTextの方に、「android:focusable="false"」を設定する。

    <EditText
        android:id="@+id/toolbar_title"
        android:focusable="false"
        android:focusableInTouchMode="false" />

    <EditText
        android:id="@+id/note_edit_body" />

「当てたい方」をどうにかするのではなく、「当てたくない方」をどうにかするわけだ。

これで、「上段のEditText(@+id/toolbar_title)」に初期フォーカスは当たらなくなった。

お、解決か?

いや……上記は実は「フォーカスを完全に無効」にしてしまう設定なので、このままにすると二度と「上段のEditText(@+id/toolbar_title)」にフォーカスが当たらなくなってしまう

なので、何らかの契機で、フォーカスを有効に戻してやらなければならない。

その契機は、最適だと思えるのは、やはり、「上段のEditText(@+id/toolbar_title)」をタッチされた契機、だろうか。

    // click the title of toolbar
    findViewById(R.id.toolbar_title).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            // enable & request focus
            view.setFocusable(true);
            view.setFocusableInTouchMode(true);
            view.requestFocus();

            // show soft input
            InputMethodManager imm =
                    (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            if (null != imm) {
                imm.showSoftInput(view, 0);
            }
        }
    });

上記サンプルコードでの大事なポイントは、「requestFocus()」を行っているところだ。

フォーカスを有効に戻しただけでは、フォーカス自体は当たらないので、この契機で同時に明示的にフォーカスを当ててやる必要がある。

それが「requestFocus()」だ。

また、フォーカスが当たっただけでは、ソフトキーボードは表示されないので、この契機でさらにソフトキーボードも明示的に表示してやる必要がある(※そもそも、フォーカスが当たっていないと、ソフトキーボードは表示できない)。

忘れずに「showSoftInput()」を行おう。

初めは本当に何も分からず色々と調査もして悩みに悩んだが、実現してみれば、至極理に適ったシンプルな実装ではないだろうか?

(※「minSdkVersion 21:Lollipop」を前提としたサンプルコード)

サンプルアプリ

個人的に、プロジェクト一式や操作動画を確認するよりも、アプリの実動作・見栄えを自らの手で確認したいと思うことの方が圧倒的に多い。

なので、良ければ、同じ思いの方は、以下のメモ帳アプリ(=文中のスクショのアプリ)を是非参考にしてみてほしい。

本件のフォーカス動作や、タッチしたときのソフトキーボード表示など、違和感なく出来ていると思う。

ic_launcher.png
シンプルなメモ帳は文字数もカウントする-様々なカスタマイズ機能を搭載した無料ノート-NOTEBOSS

【動作環境】
Android OS 5.0以上

Made in Japan.
© CUTBOSS
Producer & Director, Boss of the Barber.
Lead Programmer & Designer, Boss of the Barber.

header_2_ja.png

関連記事

参考記事

8
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
9