如何捕获 SearchView 的清除按钮点击?

Posted

技术标签:

【中文标题】如何捕获 SearchView 的清除按钮点击?【英文标题】:How do I capture SearchView's clear button click? 【发布时间】:2014-09-07 18:48:51 【问题描述】:

如何通过单击右侧的 X 按钮捕获用户单击清除 SearchView 文本的事件

我已经捕获了onQueryTextChange 事件,但是,这是针对任何文本更改而不是针对那个 X 按钮

【问题讨论】:

我也在寻找这个问题的答案。任何人都有链接,因为我在谷歌上搜索了过去几个小时,但找不到任何东西。 【参考方案1】:

在尝试了很多组合之后,我找到了如何在SearchView中捕捉X按钮后面的事件

下面是我的一个应用程序中onCreateOptionsMenu 函数的代码 sn-p。 mSearchMenumSearchView 是全局变量。 X实际上是一个ID为search_close_btn的ImageView,而文本区域是一个ID为search_src_text的EditText视图

@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);
    

【讨论】:

我在这里遇到了类似的问题:***.com/questions/43702055/…。 mSearchView.onActionViewExpanded() 不起作用。您对我该如何解决有什么想法或想法吗? 非常有帮助。谢谢。【参考方案2】:

你可以只使用 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;
            
        );

【讨论】:

我没有看到任何不工作的原因。除非***.com/a/14622049/4127670 也许这适用于崩溃的SearchView,但它不适用于iconifiedByDefault="false"【参考方案3】:

我在尝试通过其 ID 查找组件时遇到问题,但我找到了另一种使用相同 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.
    
);

【讨论】:

它有效,只是不要忘记相应地添加searchView.setIconified(true);searchView.setIconified(false); 这看起来很骇人 cathced java.lang.NullPointerException ((【参考方案4】:

我使用此代码来捕获文本查询清除,并执行我的操作

@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;
    

【讨论】:

简单高效。 我在使用这种方法时遇到的一个问题是,当通过单击主页/返回图标关闭搜索视图时,这似乎也会触发。就我而言,我需要为这两个单独的操作提供不同的行为。 太棒了,它看起来正是我需要的! :) 这个答案没有解决问题的关键部分 - 如何区分通过“x”按钮清除和通过按退格键直到没有文本离开。【参考方案5】:

如果你使用 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 年 8 月编辑:

如果你使用androidx:androidx.appcompat.R.id.search_close_btn

【讨论】:

谢谢,这是唯一对我有用的解决方案【参考方案6】:

如果你使用的是 androidx 的 SearchView,你可以这样做:

val closeButton: View? = searchView.findViewById(androidx.appcompat.R.id.search_close_btn)
closeButton?.setOnClickListener  
    //TODO: Set your action

【讨论】:

需要注意的是,它会覆盖 clear 功能。然后,您也应该致电searchView.setQuery("", false)【参考方案7】:
    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 作为“提交”按钮

【讨论】:

【参考方案8】:

一个 kotlin 答案:

mySearchView.setOnCloseListener(object : SearchView.OnCloseListener 
            override fun onClose(): Boolean 
                // Do your stuff
                return false
            
        )

【讨论】:

【参考方案9】:

Eduardo 的解决方案对我不起作用。我发现了其他适用于 Kotlin 的东西。感谢SjoerdvGestel,我找到了这个解决方案,它是answer。

// 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

【讨论】:

【参考方案10】:

要返回SearchView的初始状态,可以在按下“X”的时候做一个清晰的焦点,另外这个清晰的焦点隐藏了键盘。

searchview.setOnCloseListener(new SearchView.OnCloseListener() 
            @Override
            public boolean onClose() 
                searchview.clearFocus();
                return false;
            
);

【讨论】:

请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助,质量更高,更有可能吸引投票。 感谢您的澄清。【参考方案11】:

使用 (Lambda) 的 kotlin 简洁答案:

mySearchView.setOnCloseListener 
    // Do your stuff
    return false

【讨论】:

以上是关于如何捕获 SearchView 的清除按钮点击?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 中展开的 SearchView(显示 10 个最近搜索)下方添加一个按钮(如“清除历史记录”)?

捕获自动完成文本框交叉图标的事件

更改 SearchView 上的工具栏颜色/样式单击

如何以编程方式关闭 SearchView?

如何在用户点击JS中的移动设备中点击按钮时捕获事件

后退按钮不折叠 SearchView