Как зафиксировать нажатие кнопки Clear в SearchView?

Как я могу зафиксировать событие, когда пользователь нажимает на чистый текст SearchView, нажав кнопку X справа

Я уже зафиксировал событие onQueryTextChange, но это для любого изменения текста, а не для этой кнопки X


person asmgx    schedule 17.07.2014    source источник
comment
Я тоже ищу ответ на этот вопрос. У кого-нибудь есть ссылка, потому что я искал последние несколько часов в Google и ничего не нашел.   -  person Sitram    schedule 19.07.2014


Ответы (10)


Перепробовав множество комбинаций, я нашел, как зафиксировать событие за кнопкой X в SearchView.

Ниже приведен фрагмент кода из функции onCreateOptionsMenu в одном из моих приложений. mSearchMenu и mSearchView — глобальные переменные. X на самом деле является ImageView с идентификатором search_close_btn, а текстовая область представляет собой представление EditText с идентификатором search_src_text.

@SuppressLint("NewApi")
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu items for use in the action bar
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.country_list_activity_actions, menu);
        mSearchMenu = menu.findItem(R.id.action_search);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            // Get the SearchView and set the searchable configuration
            SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
            mSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();

            // Assumes current activity is the searchable activity
            mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
            mSearchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default

            // Get the search close button image view
            ImageView closeButton = (ImageView)mSearchView.findViewById(R.id.search_close_btn);

            // Set on click listener
            closeButton.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    LoggerUtils.d(LOG, "Search close button clicked");
                    //Find EditText view
                    EditText et = (EditText) findViewById(R.id.search_src_text);

                    //Clear the text from EditText view
                    et.setText("");

                    //Clear query
                    mSearchView.setQuery("", false);
                    //Collapse the action view
                    mSearchView.onActionViewCollapsed();
                    //Collapse the search widget
                    mSearchMenu.collapseActionView();
                }
            });
        }

        // When using the support library, the setOnActionExpandListener() method is
        // static and accepts the MenuItem object as an argument
        mSearchMenu.setOnActionExpandListener(new OnActionExpandListener() {

            @Override
            public boolean onMenuItemActionExpand(MenuItem item) {
                //Nothing to do here
                LoggerUtils.d(LOG, "Search widget expand ");
                return true; // Return true to expand action view
            }

            @Override
            public boolean onMenuItemActionCollapse(MenuItem item) {
                LoggerUtils.d(LOG, "Search widget colapsed ");
                return true; // Return true to collapse action view
            }
        });

        return super.onCreateOptionsMenu(menu);
    }
person Sitram    schedule 19.07.2014
comment
У меня есть аналогичная проблема здесь: stackoverflow.com/questions/43702055/. mSearchView.onActionViewExpanded() не работает. Есть ли у вас какие-либо мысли или идеи о том, как я могу исправить? - person AJW; 30.04.2017
comment
Очень полезно. Спасибо. - person Pooja; 09.10.2019

вы можете просто использовать onCloseListener()

sv= (SearchView) findViewById(R.id.searchView1);

sv.setOnCloseListener(new OnCloseListener() {
            @Override
            public boolean onClose() {
                Toast t = Toast.makeText(MainActivity.this, "close", Toast.LENGTH_SHORT);
                t.show();

                return false;
            }
        });
person spaceMonkey    schedule 06.11.2014
comment
не вижу причин не работать. если stackoverflow.com/a/14622049/4127670 - person spaceMonkey; 02.02.2015
comment
Возможно, это работает на разрушающемся SearchView, но у меня не работает с iconifiedByDefault="false" - person Richard Le Mesurier; 18.01.2016

У меня были проблемы с поиском компонента по его идентификатору, но я нашел другой способ поиска этого компонента, используя контекст того же SearchView

// Catch event on [x] button inside search view
int searchCloseButtonId = searchView.getContext().getResources()
                .getIdentifier("android:id/search_close_btn", null, null);
ImageView closeButton = (ImageView) this.searchView.findViewById(searchCloseButtonId);
// Set on click listener
closeButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
       // Manage this event.
    }
});
person Jhegs    schedule 21.07.2014
comment
Это работает, только не забудьте добавить searchView.setIconified(true); или searchView.setIconified(false); соответственно - person Gidi Sprintzin; 16.11.2016
comment
Это выглядит хакерским - person Sharp Edge; 28.12.2017
comment
поймал java.lang.NullPointerException (( - person Serg Burlaka; 16.10.2018

Я использую этот код, чтобы поймать очистку текстового запроса и выполнить свои действия

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

        SearchView searchView = (SearchView) menu.findItem(R.id.search_button).getActionView();
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

        SearchView.OnQueryTextListener textChangeListener = new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextChange(String cs) {
                if (TextUtils.isEmpty(cs)){
                    //Text is cleared, do your thing
                }
                return false;
            }

            @Override
            public boolean onQueryTextSubmit(String query) {
                //text query submitted
            }
        };
        searchView.setOnQueryTextListener(textChangeListener);

        return true;
    }
person Rafael    schedule 25.09.2015
comment
Просто и эффективно. - person Alexandre Prazeres; 14.07.2017
comment
Одна проблема, с которой я столкнулся при использовании этого подхода, заключается в том, что он также срабатывает, когда окно поиска закрывается нажатием значка «Домой/Назад». В моем случае мне нужно было другое поведение для этих двух отдельных действий. - person user1689757; 12.11.2017
comment
Отлично, выглядит то, что мне нужно! :) - person Serg Burlaka; 16.10.2018
comment
Этот ответ не затрагивает ключевую часть вопроса - как различать очистку с помощью кнопки «x» и очистку с помощью нажатия клавиши Backspace до тех пор, пока не останется текста. - person Joeleski; 20.12.2018

Если вы используете библиотеку Appcompat, вместо использования

getResources().getIdentifier("android:id/search_close_btn", null, null);

вы можете сделать это:

MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
View closeButton = searchView.findViewById(android.support.v7.appcompat.R.id.search_close_btn);
                closeButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //handle click
                    }
                });

ИЗМЕНИТЬ АВГУСТ 2019 Г.:

Если вы используете androidx: androidx.appcompat.R.id.search_close_btn

person leon    schedule 08.03.2016
comment
Спасибо, это единственное решение, которое сработало для меня - person DIRTY DAVE; 05.03.2021

Если вы используете SearchView из androidx, вы можете сделать это:

val closeButton: View? = searchView.findViewById(androidx.appcompat.R.id.search_close_btn)
closeButton?.setOnClickListener { 
    //TODO: Set your action
}
person GianMS    schedule 26.06.2020
comment
Предостережение в том, что он переопределяет четкую функциональность. Затем вы также должны позвонить searchView.setQuery("", false). - person djserva; 18.02.2021

    ImageView closeButton = (ImageView) this.searchView.findViewById(android.support.v7.appcompat.R.id.search_close_btn);

    closeButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // Manage this event.


        }
    });

Используйте R.id.search_go_btn для кнопки «Отправить»

person VINAY DANARADDI    schedule 18.08.2017

Котлин ответ:

mySearchView.setOnCloseListener(object : SearchView.OnCloseListener {
            override fun onClose(): Boolean {
                // Do your stuff
                return false
            }
        })
person Eduardo Viana    schedule 10.08.2018

Решение от Эдуардо у меня не работает. Я нашел кое-что еще, что работает для Kotlin. Я нашел это решение благодаря SjoerdvGestel и его ответу.

// Get the close button on the searchView
val closeButtonId: Int = searching.context.resources.getIdentifier("android:id/search_close_btn", null, null)
val closeButton = searching.findViewById(closeButtonId) as ImageView

// On close collapse the searchView
closeButton.setOnClickListener {
    searching.onActionViewCollapsed()
    true
}
person yanis labrak    schedule 15.05.2020

Для возврата в исходное состояние SearchView можно сделать четкий фокус при нажатии X, кроме того, этот четкий фокус скрывает клавиатуру.

searchview.setOnCloseListener(new SearchView.OnCloseListener() {
            @Override
            public boolean onClose() {
                searchview.clearFocus();
                return false;
            }
});
person Lautaro Villarreal Culic'    schedule 20.01.2021
comment
Пожалуйста, не публикуйте только код в качестве ответа, но также объясните, что делает ваш код и как он решает проблему вопроса. Ответы с объяснением, как правило, более полезны и качественны, и с большей вероятностью привлекут положительные голоса. - person Zsolt Meszaros; 20.01.2021
comment
Спасибо за разъяснения. - person Lautaro Villarreal Culic'; 20.01.2021