Androidアプリで起動時のEditTextへのフォーカスを外す方法【Java】

AndroidでEditTextへのフォーカスを外す方法

起動時のEditTextへのフォーカスを外す方法

概要

AndroidではActivity起動時に画面内最初のEditTextにフォーカスされます。便利な機能ですが自動でフォーカスしてほしくない場合もあります。

この自動フォーカスを防ぐ方法ともっと詳しく知っておきたい方のためにAndroidのフォーカスの仕組みをまとめます。

他のViewにフォーカスを当てたい場合

AndroidでEditTextへのフォーカスを外す方法

xmlで指定する方法

他にフォーカスを当てたいViewがある場合には、そのViewにrequestFocusを追加します。


<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
        
        <EditText
            android:id="@+id/sample_editText1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="入力項目1"
            />
        
        <EditText
            android:id="@+id/sample_editText2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="入力項目2">
                
                <requestFocus/>
                
        </EditText>
        
        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="ボタン"
            />

</LinearLayout>

この例ではEditText2つとButton1つがあります。特に何もせずに起動すると入力項目1のEditTextにフォーカスされます。

これを入力項目2のほうにフォーカスさせたいというような場合、2つ目のEditTextの中にrequestFocusを追加することで起動時に入力項目2のほうにフォーカスされ、入力項目1からはフォーカスが外れます。

コードで指定する場合

xmlで指定するのと同じことをJavaコードでやる場合には以下のようになります。


import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity{

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EditText sample2 = findViewById(R.id.sample_editText2);
        sample2.requestFocus();
    }
}

入力項目2のEditTextからrequestFocus()メソッドを呼ぶことで入力項目1のフォーカスが外れて入力項目2にフォーカスされます。

単にフォーカスを外したい場合

AndroidでEditTextへのフォーカスを外す方法

xmlで指定する方法

以下の例では親要素のLinearLayoutのandroid:focusableInTouchModeをtrueにしています。


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	android:id="@+id/linearLayout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity"
    android:focusableInTouchMode="true">
        <EditText
            android:id="@+id/sample_editText1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="入力項目1"
            />

        <EditText
            android:id="@+id/sample_editText2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="入力項目2">
        </EditText>

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="ボタン"
            />

</LinearLayout>

こうすることで入力項目1より先に親要素のLinearLayoutにフォーカスされることになり、結果的に入力項目1からフォーカスが外れます。

他には空の要素を追加するという方法もあります。


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	android:id="@+id/linearLayout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:focusableInTouchMode="true" />

        <EditText
            android:id="@+id/sample_editText1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="入力項目1"
            />

        <EditText
            android:id="@+id/sample_editText2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="入力項目2">
        </EditText>

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="ボタン"
            />

</LinearLayout>

空のLinearLayoutを作りandroid:focusableInTouchModeをtrueにしています。

これも同じくEditTextよりも先に空のLinearLayoutにフォーカスされるので結果的に入力項目1からフォーカスが外れます。当然この空要素はEditTextよりも上に配置されていないと意味がないので注意してください。

コードで指定する場合

xmlで指定するのと同じことをJavaコードでやる場合は以下のようになります。


import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity{

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        LinearLayout linearLayout = findViewById(R.id.linearLayout);
        linearLayout.setFocusableInTouchMode(true);

    }
}

親要素のLinearLayoutにsetFocusableInTouchMode()メソッドでtrueを渡しています。

Androidのフォーカスの仕組み

タッチモードと非タッチモード

Androidにはタッチモードとタッチモードではないモード(非タッチモード)が用意されています。

タッチモードとは画面タッチで操作するモードで、非タッチモードとはトラックボール、十字キー(方向キー)、キーボードのTABキーなどで操作するモードです。画面内の部品にフォーカスを当てるという点において、これらのモードには微妙な違いがあります。

例えば、EditTextは文字を入力するためにタッチモードでも非タッチモードでもフォーカスを当てて操作することになるので2つのモードに違いはありません。しかし、Buttonは非タッチモードではEnterキー(決定キー)を押すためにフォーカスを当てる必要がありますが、タッチモードではタッチによってButtonの処理が呼び出されるのでフォーカスを当てる必要はありません。

この違いに対応するためにfocusableという設定とfocusableInTouchModeという設定の2つが用意されています。

focusableとfocusableInTouchMode

focusableとはフォーカスを当てることができるかという設定です。focusableのデフォルト値は以下のようになっています。

LinearLayout false
TextView false
CheckBox true
SeekBar true
EditText true
Button true

入力項目として使うようなViewはフォーカスが当てられるようにtrue、LinearLayoutやTextViewなどの入力に関係のないViewはフォーカスを当てる必要がないのでfalseとなっています。

対して、focusableInTouchModeとはタッチモードのときにフォーカスを当てられるかという設定です。focusableInTouchModeのデフォルト値は以下のようになっています。

LinearLayout false
TextView false
CheckBox false
SeekBar false
EditText true
Button false

入力項目として使うViewの中でもタッチするだけで処理できるものはfalseになっています。

Activity起動時にEditTextに自動でフォーカスされるのは、画面内で一番上にあるfocusableInTouchModeがtrueのViewを検索しているからです。したがって、EditTextよりも優先されるfocusableInTouchModeがtrueのViewを用意してあげるとEditTextからのフォーカスを外すことができます。

ちなみに、ScrollViewなどを用いてActivity起動時にEditTextが画面外になるような構造の場合はそもそも自動でフォーカスされることはありません。

投稿されたコメント一覧

コメント投稿フォーム

必須項目
任意項目

ウェブサービス一覧