У меня есть Activity
в Android с двумя элементами:
EditText
ListView
Когда мой Activity
запускается, EditText
сразу получает фокус ввода (мигающий курсор). Я не хочу, чтобы какой-либо элемент управления имел фокус ввода при запуске. Я старался:
EditText.setSelected(false);
EditText.setFocusable(false);
Не повезло. Как я могу убедить EditText
не выбирать себя при запуске Activity
?
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"/>
Реальная проблема заключается в том, что вы просто не хотите, чтобы она была в центре внимания? Или вы не хотите, чтобы виртуальная клавиатура отображалась в результате фокусировки на 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();
Хороший комментарий от Гийома Перро:
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
не получит фокус после начала действия
Проблема, похоже, связана со свойством, которое я вижу только в 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>
Используя информацию, предоставленную другими плакатами, я применил следующее решение:
в макете 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 при создании, но захватят его, когда вы к ним прикоснетесь.
<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 https://stackoverflow.com/a/8639921/15695)
И удалить
<requestFocus />
В EditText
(Ссылка из floydaddict https://stackoverflow.com/a/9681809)
Поздний, но самый простой ответ, просто добавьте его в родительский макет 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"
Вы можете просто установить для "focusable" и "focusable in touch mode" значение 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);
Поскольку мне не нравится загрязнять 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;
}
Напишите эту строку в родительском макете ...
android:focusableInTouchMode="true"
Поздно, но может быть полезно. Создайте фиктивный 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" />
Просто поместите это как представление перед проблемным сфокусированным представлением, и все.
<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"/>
Самое простое, что я сделал, - это сосредоточился на другом представлении в onCreate:
myView.setFocusableInTouchMode(true);
myView.requestFocus();
Это остановило появление программной клавиатуры, и в 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);
Похожие вопросы
Новые вопросы
android
Android - это мобильная операционная система Google, используемая для программирования или разработки цифровых устройств (смартфоны, планшеты, автомобили, телевизоры, одежда, стекло, IoT). Для тем, связанных с Android, используйте специальные теги Android, такие как android-intent, android-activity, android-адаптер и т. Д. Для вопросов, не связанных с разработкой или программированием, но связанных с платформой Android, используйте эту ссылку: https: // android.stackexchange.com .