Отключите клавиатуру, когда вы нажимаете вне EditText в android
У меня есть EditText
, называемый myTextview
. Я хочу, чтобы мягкая клавиатура отображалась, когда я нажимаю на EditText
, но затем увольняюсь, если я выхожу за пределы EditText
. Поэтому я использую метод ниже. Но клавиатура не убирается, когда я нажимаю внешний вид (я нажимаю TextView
). Как исправить этот код?
myTextview.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
} else {
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myTextview.getWindowToken(), 0);
}
}
});
Ответы
Ответ 1
Я нашел лучшее решение:
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
View v = getCurrentFocus();
if (v != null &&
(ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) &&
v instanceof EditText &&
!v.getClass().getName().startsWith("android.webkit.")) {
int scrcoords[] = new int[2];
v.getLocationOnScreen(scrcoords);
float x = ev.getRawX() + v.getLeft() - scrcoords[0];
float y = ev.getRawY() + v.getTop() - scrcoords[1];
if (x < v.getLeft() || x > v.getRight() || y < v.getTop() || y > v.getBottom())
hideKeyboard(this);
}
return super.dispatchTouchEvent(ev);
}
public static void hideKeyboard(Activity activity) {
if (activity != null && activity.getWindow() != null && activity.getWindow().getDecorView() != null) {
InputMethodManager imm = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(activity.getWindow().getDecorView().getWindowToken(), 0);
}
}
Это применимо, даже если вы работаете с веб-просмотром.
font: http://kuznetsow.com/?p=196&lang=en
Ответ 2
Может быть, немного проще:
Установите focusChangedListener на свой текст редактирования, а затем просто спрячьте клавиатуру, если у вас нет фокуса.
yourEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus){
hideKeyboard();
}
}
});
private void hideKeyboard() {
InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(yourEditText.getWindowToken(), 0);
}
Ответ 3
используйте следующий код.
public static void hideSoftKeyboard(Activity activity) {
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}
он работает для меня.
Ответ 4
Таким образом, клавиатура исчезнет только при касании вида, который может получить фокус. Я предлагаю вам сделать следующее:
Создайте пользовательскую ViewGroup следующим образом:
public class TouchLayout extends LinearLayout {
private OnInterceptTouchEventListener mListener;
public TouchLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if(mListener != null) {
return mListener.onInterceptTouchEvent(event);
}
return super.onInterceptTouchEvent(event);
}
public void setOnInterceptTouchEventListener(OnInterceptTouchEventListener listener) {
mListener = listener;
}
public interface OnInterceptTouchEventListener {
public boolean onInterceptTouchEvent(MotionEvent event);
}
}
Затем добавьте пользовательский вид в качестве корня вашего макета xml:
<com.example.TouchLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
В вашей деятельности вы должны сделать следующее:
final TouchLayout root = (TouchLayout) findViewById(R.id.root);
final EditText text = (EditText) findViewById(R.id.text);
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
root.setOnInterceptTouchEventListener(new OnInterceptTouchEventListener() {
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
final View v = getCurrentFocus();
if(v != null && v.equals(text)) {
final int screenCords[] = new int[2];
text.getLocationOnScreen(screenCords);
final Rect textRect = new Rect(screenCords[0], screenCords[1], screenCords[0] + text.getWidth(), screenCords[1] + text.getHeight());
if(!textRect.contains(event.getRawX(), event.getRawY() {
imm.hideSoftInputFromWindow(myTextview.getWindowToken(), 0);
// Optionally you can also do the following:
text.setCursorVisible(false);
text.clearFocus();
}
}
return false;
}
};
Ответ 5
Просьба: Я признаю, что у меня нет влияния, но, пожалуйста, серьезно отнеситесь к моему ответу.
Проблема: Отключите мягкую клавиатуру при нажатии на клавиатуре или редактировании текста с минимальным кодом.
Решение: Внешняя библиотека, известная как Butterknife.
Однолинейное решение:
@OnClick(R.id.activity_signup_layout) public void closeKeyboard() { ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); }
Более читаемое решение:
@OnClick(R.id.activity_signup_layout)
public void closeKeyboard() {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
Объяснение: Привязать прослушиватель OnClick к идентификатору родительского элемента XML-макета активности, чтобы любой щелчок по макету (а не редактированию текста или клавиатуры) запустил этот фрагмент кода, который скроет клавиатуру.
Пример: Если ваш файл макета - R.layout.my_layout, а ваш идентификатор макета - R.id.my_layout_id, тогда ваш вызов привязки Butterknife должен выглядеть так:
(@OnClick(R.id.my_layout_id)
public void yourMethod {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
Ссылка на документацию Butterknife: http://jakewharton.github.io/butterknife/
Plug: Butterknife произведет революцию в развитии Android. Подумайте об этом.
Ответ 6
Событие Touch в представлении начнется с ACTION_DOWN
, которое будет передано сверху на этот вид в виде иерархии. Переопределите dispatchTouchEvent
, чтобы делать дополнительные вещи. Вот пример, чтобы перейти от FrameLayout
в kotlin:
class TLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet?=null):
FrameLayout(context, attrs){
var preDispatchTouchEvent: ((ev: MotionEvent?)->Boolean)? = null
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
if (preDispatchTouchEvent==null || !preDispatchTouchEvent!!.invoke(ev)) {
super.dispatchTouchEvent(ev)
}
return true
}
}
Оберните EditText
и другие относительные View
в этом макете и установите preDispatchTouchEvent
для отклонения EditText
, когда событие не находится над ним.
Проверьте этот вопрос OS и официальный документ, чтобы иметь более глубокое понимание касания доставки событий.
Ответ 7
Xamarin Android-код для этого:
public override bool DispatchTouchEvent(MotionEvent ev)
{
try
{
View view = CurrentFocus;
if (view != null && (ev.Action == MotionEventActions.Up || ev.Action == MotionEventActions.Move) && view is EditText && !view.Class.Name.StartsWith("android.webkit."))
{
int[] Touch = new int[2];
view.GetLocationOnScreen(Touch);
float x = ev.RawX + view.Left - Touch[0];
float y = ev.RawY + view.Top - Touch[1];
if (x < view.Left || x > view.Right || y < view.Top || y > view.Bottom)
((InputMethodManager)GetSystemService(InputMethodService)).HideSoftInputFromWindow((Window.DecorView.ApplicationWindowToken), 0);
}
}
catch (System.Exception ex)
{
}
return base.DispatchTouchEvent(ev);
}