Хорошо, все знают, что для того, чтобы спрятать клавиатуру, вам нужно реализовать:
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
Но главное здесь в том, как спрятать клавиатуру, когда пользователь касается или выбирает любое другое место, которое не является EditText
или софт-клавиатурой?
Я попытался использовать onTouchEvent()
родительский Activity
элемент, но это работает только в том случае, если пользователь касается внешнего вида, а прокрутки нет.
Я пытался реализовать касание, щелчок, фокусировку слушателя без какого-либо успеха.
Я даже пытался реализовать свой собственный вид прокрутки для перехвата сенсорных событий, но я могу получить только координаты события, а не вид, по которому щелкнули.
Есть ли стандартный способ сделать это ?? в iPhone это было действительно легко.
android
android-softkeyboard
htafoya
источник
источник
getFields()
здесь: stackoverflow.com/questions/7790487/…Ответы:
Следующий фрагмент просто скрывает клавиатуру:
Вы можете поместить это в служебный класс или, если вы определяете его в действии, избегать параметра активности или вызывать
hideSoftKeyboard(this)
.Самое сложное - это когда это назвать. Вы можете написать метод, который повторяет каждый элемент
View
в вашей активности, и проверить, являетсяinstanceof EditText
ли онsetOnTouchListener
элементом, если он не зарегистрирован в этом компоненте, и все станет на свои места. Если вам интересно, как это сделать, это на самом деле довольно просто. Вот что вы делаете, вы пишете рекурсивный метод, подобный следующему, на самом деле вы можете использовать это, чтобы делать что угодно, например, настраивать пользовательские гарнитуры и т. Д.Вот и все, просто вызовите этот метод после вас
setContentView
в вашей деятельности. Если вам интересно, какой параметр вы бы передали, этоid
родительский контейнер. Назначьтеid
родительский контейнер как<RelativeLayoutPanel android:id="@+id/parent"> ... </RelativeLayout>
и позвони
setupUI(findViewById(R.id.parent))
, вот и все.Если вы хотите использовать это эффективно, вы можете создать расширенный
Activity
и вставить этот метод, а также заставить все остальные действия в вашем приложении расширять это действие и вызывать егоsetupUI()
вonCreate()
методе.Надеюсь, поможет.
Если вы используете более 1 действия, определите общий идентификатор для родительского макета, например
<RelativeLayout android:id="@+id/main_parent"> ... </RelativeLayout>
Затем расширяйте класс из
Activity
и определяйтеsetupUI(findViewById(R.id.main_parent))
внутри негоOnResume()
и расширяйте этот класс вместо `` Activityin your program
Вот версия Kotlin вышеупомянутой функции:
источник
if(activity.getCurrentFocus() != null) {...}
OnTouchListener
их. Вы можете просто установить эту логику вViewGroup.onInterceptTouchEvent(MotionEvent)
корневое представление.Вы можете достичь этого, выполнив следующие действия:
Сделайте родительский вид (контентный вид вашей деятельности) кликабельным и фокусируемым, добавив следующие атрибуты
Реализуйте метод hideKeyboard ()
Наконец, установите onFocusChangeListener вашего текста редактирования.
Как указано в одном из комментариев ниже, это может не сработать, если родительским представлением является ScrollView. В этом случае clickable и focusableInTouchMode могут быть добавлены в представление непосредственно под ScrollView.
источник
clickable
иfocusableInTouchMode
к моему корневомуScrollView
элементу. Я должен был добавить к прямому родителю моего,EditText
который былLinearLayout
.Просто переопределите код ниже в Activity
источник
Я считаю принятый ответ немного сложным.
Вот мое решение. Добавьте
OnTouchListener
к своему основному макету, т.е.и поместите следующий код в метод onTouch.
Таким образом, вам не нужно перебирать все представления.
источник
android:onClick="stealFocusFromEditTexts"
в xml родительского представления, а затемpublic void stealFocusFromEditTexts(View view) {}
в его действие. Метод по щелчку не должен ничего делать, он просто должен существовать, чтобы родительское представление было фокусируемым / выбираемым, что необходимо для кражи фокуса у дочернего элемента EditTextУ меня есть еще одно решение, чтобы скрыть клавиатуру:
Здесь проходят
HIDE_IMPLICIT_ONLY
в положенииshowFlag
и0
в положенииhiddenFlag
. Это принудительно закроет мягкую клавиатуру.источник
Ну, мне удается несколько решить проблему, я переопределил dispatchTouchEvent в своей деятельности, там я использую следующее, чтобы скрыть клавиатуру.
РЕДАКТИРОВАТЬ: метод getFields () это просто метод, который возвращает массив с текстовыми полями в представлении. Чтобы избежать создания этого массива при каждом касании, я создал статический массив с именем sFields, который возвращается методом getFields (). Этот массив инициализируется в методах onStart (), таких как:
sFields = new EditText[] {mUserField, mPasswordField};
Это не идеально, время события перетаскивания основано только на эвристике, поэтому иногда оно не скрывается при выполнении длинных щелчков, и я также закончил, создав метод, чтобы получить все editTexts для представления; иначе клавиатура будет скрываться и показываться при нажатии другого EditText.
Тем не менее, более чистые и короткие решения приветствуются
источник
getFields()
метод? Он не должен быть точным, просто пример с несколькими комментариями, указывающими, что он возвращает массивEditText
объектов.Используйте OnFocusChangeListener .
Например:
Обновление : вы также можете изменить
onTouchEvent()
свою активность и проверить координаты касания. Если координаты находятся вне EditText, то скройте клавиатуру.источник
Я реализовал dispatchTouchEvent в Activity, чтобы сделать это:
и я проверил, работает отлично!
источник
Более удобный способ Kotlin & Material Design с использованием TextInputEditText (этот подход также совместим с EditTextView ) ...
1. Сделайте родительский вид (представление содержимого вашей деятельности / фрагмента) кликабельным и фокусируемым, добавив следующие атрибуты
2. Создайте расширение для всех View (например, внутри файла ViewExtension.kt):
3. Создайте BaseTextInputEditText, который наследует TextInputEditText. Реализуйте метод onFocusChanged, чтобы скрыть клавиатуру, когда вид не сфокусирован:
4. Просто вызовите ваш новый пользовательский вид в XML:
Это все. Нет необходимости изменять ваши контроллеры (фрагмент или активность) для обработки этого повторяющегося случая.
источник
Переопределить общедоступный логический dispatchTouchEvent (событие MotionEvent) в любом действии (или расширить класс действия)
И это все, что вам нужно сделать
источник
Я изменил решение Andre Luis IM. Я достиг этого:
Я создал служебный метод, чтобы скрыть программную клавиатуру так же, как это сделал Andre Luiz IM:
Но вместо того, чтобы регистрировать OnTouchListener для каждого представления, которое дает плохую производительность, я зарегистрировал OnTouchListener только для корневого представления. Поскольку событие вспыхивает до тех пор, пока оно не будет использовано (EditText является одним из представлений, которое использует его по умолчанию), если оно прибывает в корневое представление, это происходит потому, что оно не было использовано, поэтому я закрываю экранную клавиатуру.
источник
Я знаю, что эта ветка довольно старая, правильный ответ кажется верным, и существует множество рабочих решений, но я думаю, что изложенный ниже подход может иметь дополнительное преимущество в отношении эффективности и элегантности.
Мне нужно это поведение для всех моих действий, поэтому я создал класс CustomActivity, унаследованный от класса Activity, и «подключил» функцию dispatchTouchEvent . Есть в основном два условия, чтобы позаботиться о:
Это мой результат:
Примечание: Кроме того, я назначаю эти атрибуты корневому представлению, позволяя очистить фокус на каждом поле ввода и предотвращая фокусирование полей ввода на запуске действия (делая представление содержимого «фокусировщиком фокуса»):
источник
Мне понравился подход звонка,
dispatchTouchEvent
сделанный htafoya, но:Итак, я сделал это несколько проще:
Есть один недостаток:
Переключение с одного
EditText
на другоеEditText
делает клавиатуру скрытой и заново отображаемой - в моем случае это желательно, потому что это показывает, что вы переключились между двумя компонентами ввода.источник
Оправдание: Я признаю , у меня нет влияния, но пожалуйста мой ответ серьезно.
Проблема: Отключите программную клавиатуру при нажатии на клавиатуре или редактируйте текст с минимальным кодом.
Решение: Внешняя библиотека, известная как Butterknife.
Решение One Line:
Более читаемое решение:
Объяснение: Свяжите OnClick Listener с родительским идентификатором XML-макета действия, чтобы любой щелчок по макету (не по тексту редактирования или клавиатуре) запустил этот фрагмент кода, который скроет клавиатуру.
Пример: если ваш файл макета - R.layout.my_layout, а идентификатор макета - R.id.my_layout_id, то вызов связывания Butterknife должен выглядеть следующим образом:
Ссылка для документации Butterknife: http://jakewharton.github.io/butterknife/
Plug: Butterknife произведет революцию в вашем развитии Android. Учти это.
Примечание: тот же результат может быть достигнут без использования внешней библиотеки Butterknife. Просто установите OnClickListener для родительского макета, как описано выше.
источник
В kotlin мы можем сделать следующее. Не нужно повторять все представления. Это будет работать и для фрагментов.
источник
Вот еще один вариант ответа fje, который касается вопросов, поднятых сайтом.
Идея здесь состоит в том, чтобы обрабатывать действия «вниз» и «вверх» в
dispatchTouchEvent
методе . При действии «вниз» мы отмечаем текущее фокусированное представление (если оно есть) и то, было ли касание внутри него, сохраняя оба этих фрагмента информации для дальнейшего использования.При действии вверх мы сначала отправляем, чтобы позволить другому представлению потенциально сфокусироваться. Если после этого в настоящее время сфокусированное представление является первоначально сфокусированным видом, и касание вниз было внутри этого представления, то мы оставляем клавиатуру открытой.
Если в настоящее время сфокусированное представление отличается от первоначально сфокусированного представления, и это также
EditText
, то мы также оставляем клавиатуру открытой.В противном случае мы закрываем это.
Итак, подведем итог, это работает следующим образом:
EditText
клавиатуры остается открытойEditText
к другомуEditText
клавиатура остается открытой (не закрывается / не открывается)EditText
, находящемуся за пределами текущего фокуса, который не является другимEditText
, клавиатура закрываетсяEditText
чтобы вызвать контекстную панель действий (с кнопками вырезать / копировать / вставить), клавиатура остается открытой, даже если действие ВВЕРХ имело место вне сфокусированногоEditText
(который сдвинулся вниз, чтобы освободить место для CAB) , Тем не менее, обратите внимание, что когда вы нажимаете на кнопку в CAB, она закрывает клавиатуру. Это может или не может быть желательным; если вы хотите вырезать / скопировать из одного поля и вставить в другое, это было бы. Если вы хотите вставить обратно в то же самоеEditText
, это не будет.когда фокус
EditText
находится внизу экрана, и вы долго щелкаете по тексту, чтобы выделить его,EditText
фокус сохраняется, и, следовательно, клавиатура открывается так, как вы хотите, потому что мы выполняем проверку «касание в пределах границ» при действии «вниз». , а не действия.источник
это слишком просто, просто сделайте ваш недавний макет кликабельным для фокуса следующим кодом:
а затем напишите метод и OnClickListner для этой раскладки, чтобы при касании самой верхней раскладки можно было вызывать метод, в котором вы будете писать код для отклонения клавиатуры. ниже приведен код для обоих; // вы должны написать это в OnCreate ()
Метод вызывается из listner:
источник
Я нахожу принятый ответ немного сложным для этого простого требования. Вот что сработало у меня без сбоев.
источник
NestedScrollView
или сложные макеты, см. Принятый ответ: stackoverflow.com/a/11656129/2914140 . Вы должны знать, что другие контейнеры могут потреблять прикосновения.Существует более простой подход, основанный на той же проблеме iPhone. Просто переопределите макет фона на сенсорном событии, где содержится текст редактирования. Просто используйте этот код в OnCreate действия (login_fondo - корневой макет):
источник
Способ показать / скрыть программную клавиатуру
Я надеюсь, что они были полезны
источник
Это самое простое решение для меня (и разработанное мной).
Это способ скрыть клавиатуру.
Теперь установите атрибут onclick родительского макета действия в метод выше,
hideKeyboard
либо из представления Design вашего XML-файла, либо написав приведенный ниже код в текстовом представлении XML-файла.источник
Я усовершенствовал метод, поместил следующий код в некоторый служебный класс пользовательского интерфейса (желательно, не обязательно), чтобы к нему можно было получить доступ из всех ваших классов Activity или Fragment для достижения своей цели.
Затем, например, скажите, что вам нужно вызвать его из действия, позвоните следующим образом;
уведомление
Это дает нам корневое представление текущей группы (вы не должны были устанавливать идентификатор в корневом представлении).
Ура :)
источник
Попытайтесь включить stateHidden как вашу деятельность
windowSoftInputMode
значенияhttp://developer.android.com/reference/android/R.attr.html#windowSoftInputMode
Например, для вашей деятельности:
источник
Деятельность
ScreenUtils
источник
Просто добавьте этот код в класс @Overide
источник
Вместо перебора всех представлений или переопределения dispatchTouchEvent.
Почему бы просто не переопределить onUserInteraction () в Activity, это будет гарантировать, что клавиатура будет закрываться всякий раз, когда пользователь нажимает за пределами EditText.
Будет работать, даже если EditText находится внутри scrollView.
источник
Я получил это работая с небольшим вариантом решения Фернандо Камараго. В моем методе onCreate я присоединяю один onTouchListener к корневому представлению, но отправляю представление, а не деятельность в качестве аргумента.
В отдельном классе Utils есть ...
источник
Это может быть старым, но я получил это путем реализации пользовательского класса
Лучше всего создать класс Helper, и каждый контейнер Relative / Linear Layouts должен реализовать это.
**** Обратите внимание, что только основной Контейнер должен реализовывать этот класс (Для оптимизации) ****
и реализовать это так:
ключевое слово это для деятельности. поэтому, если вы находитесь на фрагменте, вы используете как getActivity ();
--- недурно, если это поможет тебе ... --- ура Ральф ---
источник
Это слегка измененная версия ответа fje, которая в основном работала идеально.
Эта версия использует ACTION_DOWN, поэтому выполнение действия прокрутки также закрывает клавиатуру. Это также не распространяет событие, если вы не нажмете другой EditText. Это означает, что нажатие в любом месте за пределами вашего EditText, даже на другое нажатие, просто закрывает клавиатуру.
источник
view
иviewTmp
кgetCurrentFocus()
, так что они всегда будут иметь то же значение.Я сделал так:
Скрыть код клавиатуры :
Выполнено
источник