Как сделать SearchView потерять фокус и свернуть при нажатии в другом месте на activity

в моем приложении, я делаю поиска, в котором SearchView сворачивается и расширяется, когда он теряет и получает фокус соответственно. Однако потеря фокуса происходит только в двух случаях:

  1. при нажатии кнопки "Назад".

  2. когда значок дома рядом с SearchView нажата.

Я хочу, чтобы он потерял фокус (и, следовательно, свернуть), если пользователь нажимает не только на эти два вещи, но в любом месте экрана (например, любая кнопка или любая пустая часть экрана без просмотра на нем).

3 ответов


Ну, я нашел следующее решение. Я использовал setOnTouchListener на каждый вид, что не экземпляр searchview, чтобы свернуть searchview. Это сработало идеально для меня. Ниже приведен код.

public void setupUI(View view) {

    if(!(view instanceof SearchView)) {

        view.setOnTouchListener(new OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event) {
                searchMenuItem.collapseActionView();
                return false;
            }

        });
    }

    //If a layout container, iterate over children and seed recursion.
    if (view instanceof ViewGroup) {

        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {

            View innerView = ((ViewGroup) view).getChildAt(i);

            setupUI(innerView);
        }
    }
}

этой это ответ, о котором я говорил.


это работает для меня, mOptionsMenu сохраняется в onCreateOptionsMenu:

public void setupUI(View view) {

    //Set up touch listener for non-text box views to hide keyboard.
    if(!(view instanceof EditText)) {

        view.setOnTouchListener(new View.OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event) {
                hideSoftKeyboard(MainActivity.this);
                if(mOptionsMenu == null) return false;
                MenuItem searchMenuItem = mOptionsMenu.findItem(R.id.action_search);
                if(searchMenuItem == null) return false;
                ((SearchView)searchMenuItem.getActionView()).clearFocus();
                return false;
            }

        });
    }

    //If a layout container, iterate over children and seed recursion.
    if (view instanceof ViewGroup) {

        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {

            View innerView = ((ViewGroup) view).getChildAt(i);

            setupUI(innerView);
        }
    }
}

public static void hideSoftKeyboard(Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager)  activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

Ну, у меня есть другой более простой и аккуратный способ сделать это. Если вы используете виджет поиска в качестве представления действия на панели инструментов (https://developer.android.com/guide/topics/search/search-dialog#UsingSearchWidget), Вы можете сделать SearchView потерять фокус и скрыть клавиатуру, когда пользователь касается где-либо еще на экране.

вместо итерации и настройки прослушивателей касания на каждом представлении в иерархии, кроме SearhView, вы можете просто использовать этой решение так как SearchView имеет AutoCompleteTextView в нем.

Шаг 1: Сделайте родительское представление (представление содержимого вашей деятельности) кликабельным и фокусируемым, добавив следующий атрибут

android:clickable="true"   
android:focusableInTouchMode="true"

Шаг 2: Установите OnFocusChangeListener на Автокомплект SearchView

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);

    final MenuItem search = menu.findItem(R.id.action_search);
    SearchView searchView = (SearchView) search.getActionView();

    // get a reference of the AutoCompleteTextView from the searchView
    AutoCompleteTextView searchSrcText = searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
    searchSrcText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (!hasFocus) {
                InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
                inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
            }
        }
    });
    return super.onCreateOptionsMenu(menu);
}

вот именно! Надеюсь, это полезно для будущих читателей:)