お任せで良ければ便利なフォーカス仕様なのだが……
「EditTextを複数配置した画面」構成では、画面(Activity)起動時、「最初に検出したEditText」に対してシステムは勝手にフォーカスを当ててくれる。
「入力フォーマット画面(アカウントのログイン画面とか)」などを作成時は、これはとても有難い仕様だ、フォーカスのことまで考えなくて済むのでね!
だが、、、
画面起動時、例えば、以下メモ帳アプリのスクショのように、上段のEditText(タイトルを入力...となっている部分)にはフォーカスを当てずに、下段のEditTextにまず最初にフォーカスを当てたい、ということがあった場合は、策を練らなければならない。
このメモ帳アプリの例だと、上段が「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」を前提としたサンプルコード)
サンプルアプリ
個人的に、プロジェクト一式や操作動画を確認するよりも、アプリの実動作・見栄えを自らの手で確認したいと思うことの方が圧倒的に多い。
なので、良ければ、同じ思いの方は、以下のメモ帳アプリ(=文中のスクショのアプリ)を是非参考にしてみてほしい。
本件のフォーカス動作や、タッチしたときのソフトキーボード表示など、違和感なく出来ていると思う。
シンプルなメモ帳は文字数もカウントする-様々なカスタマイズ機能を搭載した無料ノート-NOTEBOSS
【動作環境】
Android OS 5.0以上
Made in Japan.
© CUTBOSS
Producer & Director, Boss of the Barber.
Lead Programmer & Designer, Boss of the Barber.