Остановите EditText от получения фокуса при запуске Activity
У меня есть Activity
в Android, с двумя элементами:
EditText
ListView
Когда мой Activity
начинается, EditText
немедленно имеет фокус ввода (мигающий курсор). Я не хочу, чтобы какой-либо элемент управления имел фокус ввода при запуске. Я старался:
EditText.setSelected(false);
Неудачно. Как я могу убедить EditText
не выбирать себя, когда Activity
начинается?
54 ответа
Отличные ответы от Люка и Марка, однако хороший пример кода отсутствует. Добавление тега android:focusableInTouchMode="true"
в <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
сосредоточиться на старте, но, безусловно, проблема заключается в том, чтобы открыть окно 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();
Хороший комментарий от Guillaume Perrot:
android:descendantFocusability="beforeDescendants"
кажется по умолчанию (целое значение равно 0). Это работает просто добавивandroid:focusableInTouchMode="true"
,
На самом деле, мы можем видеть, что beforeDescendants
установить по умолчанию в ViewGroup.initViewGroup()
метод (Android 2.2.2). Но не равно 0. ViewGroup.FOCUS_BEFORE_DESCENDANTS = 0x20000;
Спасибо Гийому.
Единственное решение, которое я нашел, это:
- Создать LinearLayout (я не знаю, будут ли работать другие виды Layout)
- Установите атрибуты
android:focusable="true"
а такжеandroid:focusableInTouchMode="true"
И EditText
не получит фокус после начала деятельности
Проблема, кажется, исходит от свойства, которое я вижу только в 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();
}
Попробуйте clearFocus() вместо setSelected(false)
, Каждое представление в Android имеет как фокусируемость, так и возможность выбора, и я думаю, что вы хотите просто очистить фокус.
Следующее действие остановит редактирование текста при создании фокуса, но захватите его, когда дотронетесь до них.
<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, то есть не используете событие, поведение фокусировки будет продолжаться как обычно.
Я попробовал несколько ответов по отдельности, но фокус все еще на EditText. Мне удалось решить это, используя два из нижеприведенного решения вместе.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mainLayout"
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true" >
(Ссылка от Silver /questions/11719942/ostanovite-edittext-ot-polucheniya-fokusa-pri-zapuske-activity/11719960#11719960)
и удалить
<requestFocus />
на EditText
(Ссылка от floydaddict /questions/11719942/ostanovite-edittext-ot-polucheniya-fokusa-pri-zapuske-activity/11720032#11720032)
Самый простой ответ, просто добавьте это в родительский макет XML.
android:focusable="true"
android:focusableInTouchMode="true"
Ни одно из этих решений не помогло мне. Способ, которым я исправляю автофокус, был:
<activity android:name=".android.InviteFriendsActivity" android:windowSoftInputMode="adjustPan">
<intent-filter >
</intent-filter>
</activity>
Простое решение: в AndroidManifest
в Activity
использование тегов
android:windowSoftInputMode="stateAlwaysHidden"
Вы можете просто установить "фокусируемый" и "фокусируемый в сенсорном режиме" на значение true в первом TextView
из layout
, Таким образом, когда действие начинает TextView
будет сфокусирован, но, по своей природе, вы не увидите ничего сфокусированного на экране и, конечно, не будет отображаться клавиатура...
Следующее сработало для меня в Manifest
, Написать,
<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>
Мне нужно было очистить фокус со всех полей программно. Я просто добавил следующие два утверждения в свое основное определение макета.
myLayout.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
myLayout.setFocusableInTouchMode(true);
Вот и все. Исправил мою проблему мгновенно. Спасибо, Сильвер, за то, что указал мне правильное направление.
Добавлять android:windowSoftInputMode="stateAlwaysHidden"
в теге активности Manifest.xml
файл.
Если у вас есть другой взгляд на вашу деятельность, как 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);
Напишите эту строку в вашем родительском макете...
android:focusableInTouchMode="true"
Поскольку я не люблю загрязнять 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" />
Это, кажется, ведет себя так, как я ожидаю. Нет необходимости обрабатывать изменения конфигурации и т. Д. Мне это нужно для Activity с длинным TextView (инструкции).
Да, я сделал то же самое - создал "фиктивную" линейную схему, которая получает первоначальный фокус. Кроме того, я установил "следующие" идентификаторы фокуса, чтобы пользователь больше не мог фокусироваться после однократной прокрутки:
<LinearLayout 'dummy'>
<EditText et>
dummy.setNextFocusDownId(et.getId());
dummy.setNextFocusUpId(et.getId());
et.setNextFocusUpId(et.getId());
много работы только для того, чтобы избавиться от упора на вид..
Спасибо
Для меня то, что работает на всех устройствах, это:
<!-- 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" />
Просто поместите это как представление перед проблемным сфокусированным представлением, и все.
Самое простое, что я сделал, это установил фокус на другое представление в onCreate:
myView.setFocusableInTouchMode(true);
myView.requestFocus();
Это остановило всплывающую программную клавиатуру, и в EditText не мигало курсор.
<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"/>
Это идеальное и самое простое решение. Я всегда использую это в своем приложении.
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
Написать этот код внутри 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>
В onCreate
вашей деятельности, просто добавьте использование clearFocus()
на вашем элементе EditText. Например,
edittext = (EditText) findViewById(R.id.edittext);
edittext.clearFocus();
И если вы хотите перевести фокус на другой элемент, используйте requestFocus()
на что. Например,
button = (Button) findViewById(R.id.button);
button.requestFocus();
Самый простой способ скрыть клавиатуру - использовать setSoftInputMode
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
или вы можете использовать InputMethodManager и скрыть клавиатуру, как это.
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);