EditText, четкая фокусировка на ощупь снаружи - PullRequest
79 голосов
/ 28 января 2011

Мой макет содержит ListView, SurfaceView и EditText. Когда я нажимаю на EditText, он получает фокус и выскакивает экранная клавиатура. Когда я щелкаю где-то за пределами EditText, он все еще имеет фокус (не должен). Я думаю, я мог бы установить OnTouchListener на других видах в макете и вручную очистить фокус EditText. Но кажется слишком хакерским ...

У меня такая же ситуация в другом макете - в виде списка с различными типами элементов, некоторые из которых имеют EditText внутри. Они действуют так же, как я написал выше.

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

Я видел подобные вопросы здесь, но не нашел решения ...

Ответы [ 14 ]

1 голос
/ 28 января 2011

Чтобы потерять фокус при касании другого вида, оба вида должны быть установлены как view.focusableInTouchMode (true).

Но, похоже, использовать фокусы в сенсорном режиме не рекомендуется. Пожалуйста, посмотрите здесь: http://android -developers.blogspot.com / 2008/12 / сенсорный mode.html

0 голосов
/ 16 декабря 2018

Этот простой фрагмент кода делает то, что вы хотите

GestureDetector gestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
                KeyboardUtil.hideKeyboard(getActivity());
                return true;
            }
        });
mScrollView.setOnTouchListener((v, e) -> gestureDetector.onTouchEvent(e));
0 голосов
/ 23 марта 2015

Как подсказал @pcans, вы можете сделать это переопределением dispatchTouchEvent(MotionEvent event) в своей деятельности.

Здесь мы получаем координаты касания и сравниваем их для просмотра границ.Если касание выполняется за пределами представления, сделайте что-нибудь.

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        View yourView = (View) findViewById(R.id.view_id);
        if (yourView != null && yourView.getVisibility() == View.VISIBLE) {
            // touch coordinates
            int touchX = (int) event.getX();
            int touchY = (int) event.getY();
            // get your view coordinates
            final int[] viewLocation = new int[2];
            yourView.getLocationOnScreen(viewLocation);

            // The left coordinate of the view
            int viewX1 = viewLocation[0];
            // The right coordinate of the view
            int viewX2 = viewLocation[0] + yourView.getWidth();
            // The top coordinate of the view
            int viewY1 = viewLocation[1];
            // The bottom coordinate of the view
            int viewY2 = viewLocation[1] + yourView.getHeight();

            if (!((touchX >= viewX1 && touchX <= viewX2) && (touchY >= viewY1 && touchY <= viewY2))) {

                Do what you want...

                // If you don't want allow touch outside (for example, only hide keyboard or dismiss popup) 
                return false;
            }
        }
    }
    return super.dispatchTouchEvent(event);
}

Также нет необходимости проверять наличие и видимость представления, если макет вашей деятельности не изменяется во время выполнения (например, вы не добавляете фрагменты илизаменить / удалить виды из макета).Но если вы хотите закрыть (или сделать что-то похожее) пользовательское контекстное меню (например, в магазине Google Play при использовании меню переполнения элемента), необходимо проверить наличие вида.В противном случае вы получите NullPointerException.

0 голосов
/ 18 июля 2014

Лучший способ - использовать метод по умолчанию clearFocus()

Вы знаете, как решать коды в onTouchListener верно?

Просто позвоните EditText.clearFocus().Это очистит фокус в last EditText.

...