Остановить EditText от получения фокуса при запуске активности

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

  1. EditText
  2. ListView

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

EditText.setSelected(false);

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

30 ответов


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

<!-- 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"/>

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

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

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

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


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

<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;

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


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

  • создать LinearLayout (Я не знаю, будут ли работать другие виды макета)
  • набор атрибутов android:focusable="true" и android:focusableInTouchMode="true"

и EditText не получит Фокус после запуска activity


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

убедитесь, что удалить эту строку в конце объявления в EditText XML-теги:

<requestFocus />

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

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

   //<requestFocus /> /* <-- without this line */
</EditText>

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

в макете 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();
}

следующее остановит 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, то есть не потребляете событие, поведение фокусировки будет продолжаться как обычно.


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


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

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

(ссылка из серебра https://stackoverflow.com/a/8639921/15695)

и удалить

 <requestFocus />

В полей EditText

(ссылка от floydaddict https://stackoverflow.com/a/9681809)


ни одно из этих решений не сработало для меня. То, как я исправляю автофокус, было:

<activity android:name=".android.InviteFriendsActivity" android:windowSoftInputMode="adjustPan">
    <intent-filter >
    </intent-filter>
</activity>

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

android:windowSoftInputMode="stateAlwaysHidden"

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


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

<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>

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

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

вот и все. Исправлена моя проблема мгновенно. Спасибо, Сильвер, что указала мне правильное направление.


добавить android:windowSoftInputMode="stateAlwaysHidden" в теге действия .

источник


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

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

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

ListView.requestFocus(); 

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

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


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

<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();

добавить следующее onCreate способ:

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

будучи тем, что мне не нравится загрязнять 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;
}

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

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

это, кажется, ведет себя так, как я ожидаю. Отсутствие потребности отрегулировать изменения конфигурации, etc. Мне это было нужно для деятельности с длинным TextView (instructions).


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

<LinearLayout 'dummy'>
<EditText et>

dummy.setNextFocusDownId(et.getId());

dummy.setNextFocusUpId(et.getId());

et.setNextFocusUpId(et.getId());

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

спасибо


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

 android:focusableInTouchMode="true"

для меня то, что работало на всех устройствах, это:

    <!-- 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" />

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


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

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

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

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

это остановило мягкую клавиатуру, и курсор не мигал в EditText.


написать этот код внутри на 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>

<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"/>

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

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

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

button = (Button) findViewById(R.id.button);
button.requestFocus();

вы можете достичь этого, создав манекен EditText с шириной макета и высотой, установленной в 0dp и запросите фокус на это представление. Добавьте следующий фрагмент кода в XML-макет:

<EditText
    android:id="@+id/editText0"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:hint="@string/dummy"
    android:ems="10" 
    >
     <requestFocus />
    </EditText>