У меня есть Activity в Android с двумя элементами:

  1. EditText
  2. ListView

Когда мой Activity запускается, EditText сразу получает фокус ввода (мигающий курсор). Я не хочу, чтобы какой-либо элемент управления имел фокус ввода при запуске. Я старался:

EditText.setSelected(false);
EditText.setFocusable(false);

Не повезло. Как я могу убедить EditText не выбирать себя при запуске Activity?

3066
Mark 12 Окт 2009 в 19:03

30 ответов

Лучший ответ

Отличные ответы от Люка и Марка, однако хороший образец кода отсутствует. Добавление тегов android:focusableInTouchMode="true" и android:focusable="true" в родительский макет (например, LinearLayout или ConstraintLayout), как в следующем примере, решит проблему.

<!-- Dummy item to prevent AutoCompleteTextView from receiving focus -->
<LinearLayout
    android:focusable="true" 
    android:focusableInTouchMode="true"
    android:layout_width="0px" 
    android:layout_height="0px"/>

<!-- :nextFocusUp and :nextFocusLeft have been set to the id of this component
to prevent the dummy from receiving focus again -->
<AutoCompleteTextView android:id="@+id/autotext"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:nextFocusUp="@id/autotext" 
    android:nextFocusLeft="@id/autotext"/>
2740
Marian Paździoch 20 Апр 2020 в 07:48

Реальная проблема заключается в том, что вы просто не хотите, чтобы она была в центре внимания? Или вы не хотите, чтобы виртуальная клавиатура отображалась в результате фокусировки на EditText? Я действительно не вижу проблемы с тем, что EditText фокусируется на начале, но определенно проблема заключается в том, чтобы открыть окно softInput, когда пользователь явно не запросил фокусировку на EditText ( и откройте клавиатуру в результате).

Если проблема в виртуальной клавиатуре, см. AndroidManifest.xml element в документации.

android:windowSoftInputMode="stateHidden" - всегда скрывать при входе в активность.

Или android:windowSoftInputMode="stateUnchanged" - не меняйте его (например, не показывать его, если он еще не показан, но если он был открыт при входе в действие, оставьте его открытым).

1710
Rahul 11 Май 2021 в 07:31

Существует более простое решение. Установите эти атрибуты в родительском макете:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mainLayout"
    android:descendantFocusability="beforeDescendants"
    android:focusableInTouchMode="true" >

И теперь, когда действие начинается, этот основной макет по умолчанию получает фокус.

Кроме того, мы можем удалить фокус с дочерних представлений во время выполнения (например, после завершения дочернего редактирования), снова переключив фокус на основной макет, например:

findViewById(R.id.mainLayout).requestFocus();

Хороший комментарий от Гийома Перро:

android:descendantFocusability="beforeDescendants" кажется по умолчанию (целочисленное значение 0). Работает просто добавлением android:focusableInTouchMode="true".

Действительно, мы видим, что beforeDescendants установлен по умолчанию в методе ViewGroup.initViewGroup() (Android 2.2.2). Но не равно 0. ViewGroup.FOCUS_BEFORE_DESCENDANTS = 0x20000;

Спасибо Гийому.

1186
Samuel Liew 20 Янв 2020 в 06:43

Единственное решение, которое я нашел:

  • Создайте LinearLayout (я не знаю, будут ли работай)
  • Установите атрибуты android:focusable="true" и android:focusableInTouchMode="true"

И EditText не получит фокус после начала действия

438
peterh 18 Фев 2021 в 14:01

Проблема, похоже, связана со свойством, которое я вижу только в XML form макета.

Не забудьте удалить эту строку в конце объявления в тегах XML EditText:

<requestFocus />

Это должно дать что-то вроде этого:

<EditText
   android:id="@+id/emailField"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:inputType="textEmailAddress">

   //<requestFocus /> /* <-- without this line */
</EditText>
94
Keet Sugathadasa 21 Окт 2017 в 21:17

Используя информацию, предоставленную другими плакатами, я применил следующее решение:

в макете XML

<!-- Dummy item to prevent AutoCompleteTextView from receiving focus -->
<LinearLayout
    android:id="@+id/linearLayout_focus"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:layout_width="0px"
    android:layout_height="0px"/>

<!-- AUTOCOMPLETE -->
<AutoCompleteTextView
    android:id="@+id/autocomplete"
    android:layout_width="200dip"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dip"
    android:inputType="textNoSuggestions|textVisiblePassword"/>

в onCreate ()

private AutoCompleteTextView mAutoCompleteTextView;
private LinearLayout mLinearLayout;

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

    //get references to UI components
    mAutoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.autocomplete);
    mLinearLayout = (LinearLayout) findViewById(R.id.linearLayout_focus);
}

и, наконец, в onResume ()

@Override
protected void onResume() {
    super.onResume();

    //do not give the editbox focus automatically when activity starts
    mAutoCompleteTextView.clearFocus();
    mLinearLayout.requestFocus();
}
83
Ziem 24 Апр 2015 в 22:21

Попробуйте clearFocus () вместо setSelected(false). Каждое представление в Android имеет как фокусируемость, так и возможность выбора, и я думаю, что вы хотите просто убрать фокус.

81
Keet Sugathadasa 22 Окт 2017 в 05:09

Следующие элементы перестанут фокусироваться на edittext при создании, но захватят его, когда вы к ним прикоснетесь.

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

Итак, вы устанавливаете focusable на false в xml, но ключ находится в java, к которому вы добавляете следующий слушатель:

etBonus.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        v.setFocusable(true);
        v.setFocusableInTouchMode(true);
        return false;
    }
});

Поскольку вы возвращаете false, то есть не используете событие, поведение фокусировки будет продолжаться как обычно.

76
Ziem 24 Апр 2015 в 21:43

Я попробовал несколько ответов по отдельности, но основное внимание по-прежнему уделяется EditText. Мне удалось решить эту проблему, только используя два из приведенных ниже решений вместе.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/mainLayout"
  android:descendantFocusability="beforeDescendants"
  android:focusableInTouchMode="true" >

(Ссылка из Silver https://stackoverflow.com/a/8639921/15695)

И удалить

 <requestFocus />

В EditText

(Ссылка из floydaddict https://stackoverflow.com/a/9681809)

72
FullStackDeveloper 10 Окт 2018 в 05:49

Поздний, но самый простой ответ, просто добавьте его в родительский макет XML.

android:focusable="true" 
android:focusableInTouchMode="true"

Проголосуйте, если это вам помогло! Удачного кодирования :)

68
Rishabh Saxena 16 Май 2019 в 09:34

Ни одно из этих решений не помогло мне. Я исправил автофокус следующим образом:

<activity android:name=".android.InviteFriendsActivity" android:windowSoftInputMode="adjustPan">
    <intent-filter >
    </intent-filter>
</activity>
49
rallat 30 Ноя 2011 в 16:37

Простое решение: В AndroidManifest в теге Activity используйте

android:windowSoftInputMode="stateAlwaysHidden"
46
Piyush 27 Сен 2016 в 10:05

Вы можете просто установить для "focusable" и "focusable in touch mode" значение true на первом TextView из layout. Таким образом, когда начинается действие, TextView будет сфокусирован, но по своей природе вы не увидите ничего сфокусированного на экране и, конечно, не будет отображаться клавиатура. ..

40
bofredo 27 Сен 2013 в 18:13

Следующее работало для меня в Manifest. Писать ,

<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>
38
Piyush 27 Сен 2016 в 10:05

Мне нужно было программно очистить фокус со всех областей. Я просто добавил следующие два утверждения к своему основному определению макета.

myLayout.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
myLayout.setFocusableInTouchMode(true);

Вот и все. Решил мою проблему мгновенно. Спасибо, Сильвер, за то, что указал мне в правильном направлении.

33
jakeneff 27 Сен 2012 в 23:35

Добавьте android:windowSoftInputMode="stateAlwaysHidden" в тег активности файла Manifest.xml.

Источник

30
Piyush 27 Сен 2016 в 10:04

Если у вас есть другое представление о вашей деятельности, например ListView, вы также можете:

ListView.requestFocus(); 

В вашем onResume(), чтобы захватить фокус с editText.

Я знаю, что на этот вопрос был дан ответ, но я просто предлагаю альтернативное решение, которое сработало для меня :)

28
bofredo 27 Сен 2013 в 18:11

Попробуйте это перед своим первым редактируемым полем:

<TextView  
        android:id="@+id/dummyfocus" 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        android:text="@string/foo"
        />

----

findViewById(R.id.dummyfocus).setFocusableInTouchMode(true);
findViewById(R.id.dummyfocus).requestFocus();
24
Jack Slater 12 Июн 2011 в 00:41

Добавьте следующее в метод onCreate:

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
23
Piyush 27 Сен 2016 в 10:04

Поскольку мне не нравится загрязнять XML чем-то, что связано с функциональностью, я создал этот метод, который «прозрачно» крадет фокус у первого фокусируемого представления, а затем обязательно удаляет себя, когда это необходимо!

public static View preventInitialFocus(final Activity activity)
{
    final ViewGroup content = (ViewGroup)activity.findViewById(android.R.id.content);
    final View root = content.getChildAt(0);
    if (root == null) return null;
    final View focusDummy = new View(activity);
    final View.OnFocusChangeListener onFocusChangeListener = new View.OnFocusChangeListener()
    {
        @Override
        public void onFocusChange(View view, boolean b)
        {
            view.setOnFocusChangeListener(null);
            content.removeView(focusDummy);
        }
    };
    focusDummy.setFocusable(true);
    focusDummy.setFocusableInTouchMode(true);
    content.addView(focusDummy, 0, new LinearLayout.LayoutParams(0, 0));
    if (root instanceof ViewGroup)
    {
        final ViewGroup _root = (ViewGroup)root;
        for (int i = 1, children = _root.getChildCount(); i < children; i++)
        {
            final View child = _root.getChildAt(i);
            if (child.isFocusable() || child.isFocusableInTouchMode())
            {
                child.setOnFocusChangeListener(onFocusChangeListener);
                break;
            }
        }
    }
    else if (root.isFocusable() || root.isFocusableInTouchMode())
        root.setOnFocusChangeListener(onFocusChangeListener);

    return focusDummy;
}
19
Takhion 24 Апр 2013 в 13:26

Напишите эту строку в родительском макете ...

 android:focusableInTouchMode="true"
18
Vishal Vaishnav 26 Июл 2017 в 09:52

Поздно, но может быть полезно. Создайте фиктивный EditText в верхней части макета, затем вызовите myDummyEditText.requestFocus() в onCreate()

<EditText android:id="@+id/dummyEditTextFocus" 
android:layout_width="0px"
android:layout_height="0px" />

Похоже, я веду себя так, как я ожидал. Нет необходимости обрабатывать изменения конфигурации и т. Д. Мне это нужно для Activity с длинным TextView (инструкциями).

16
Jim 13 Фев 2011 в 01:58

Да, я сделал то же самое - создал «фиктивный» линейный макет, который получает первоначальный фокус. Кроме того, я установил идентификаторы «следующего» фокуса, чтобы пользователь больше не мог сфокусировать его после прокрутки один раз:

<LinearLayout 'dummy'>
<EditText et>

dummy.setNextFocusDownId(et.getId());

dummy.setNextFocusUpId(et.getId());

et.setNextFocusUpId(et.getId());

Много работы, чтобы просто избавиться от фокусировки на виде ..

Благодарность

14
bofredo 27 Сен 2013 в 18:13

Для меня на всех устройствах работало следующее:

    <!-- fake first focusable view, to allow stealing the focus to itself when clearing the focus from others -->

    <View
    android:layout_width="0px"
    android:layout_height="0px"
    android:focusable="true"
    android:focusableInTouchMode="true" />

Просто поместите это как представление перед проблемным сфокусированным представлением, и все.

13
android developer 14 Май 2014 в 08:02
<TextView
    android:id="@+id/TextView01"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:singleLine="true"
    android:ellipsize="marquee"
    android:marqueeRepeatLimit="marquee_forever"
    android:focusable="true"
    android:focusableInTouchMode="true"
    style="@android:style/Widget.EditText"/>
12
Satan Pandeya 31 Мар 2017 в 18:41

Самое простое, что я сделал, - это сосредоточился на другом представлении в onCreate:

    myView.setFocusableInTouchMode(true);
    myView.requestFocus();

Это остановило появление программной клавиатуры, и в EditText не было мигания курсора.

11
Lumis 3 Янв 2013 в 06:57

Это идеальное и самое простое решение, которое я всегда использую в своем приложении.

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
11
user4728480user4728480 31 Мар 2015 в 09:27

Запишите этот код внутри файла Manifest в Activity, где вы не хотите открывать клавиатуру.

android:windowSoftInputMode="stateHidden"

Файл манифеста:

 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.projectt"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="24" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
         <activity
            android:name=".Splash"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".Login"
            **android:windowSoftInputMode="stateHidden"**
            android:label="@string/app_name" >
        </activity>

    </application>

</manifest>
10
Satan Pandeya 15 Мар 2017 в 07:21

В onCreate вашей деятельности просто добавьте использование clearFocus() в свой элемент EditText. Например,

edittext = (EditText) findViewById(R.id.edittext);
edittext.clearFocus();

А если вы хотите переместить фокус на другой элемент, используйте для этого requestFocus(). Например,

button = (Button) findViewById(R.id.button);
button.requestFocus();
8
Compaq LE2202x 23 Май 2013 в 10:42

Самый простой способ скрыть клавиатуру - использовать setSoftInputMode

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

Или вы можете использовать InputMethodManager и скрыть клавиатуру вот так.

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
8
Sharath kumar 11 Сен 2017 в 10:32