如何检测SearchView的返回按钮按下?

24
我使用单个活动来显示SearchView并显示搜索结果。搜索结果只是项目的子集,因此搜索充当过滤器。一切似乎运行正常,除了我无法弄清楚如何在单击SearchView的后退按钮时恢复视图中的所有项目。
或者也许有另一种方法可以检测用户从搜索结果导航到上一个视图(在我的情况下,是相同的视图)。
谢谢

请看这里:https://dev59.com/X18e5IYBdhLWcg3wVJTH - Matei Radu
1
Matei Radu,感谢您提供的链接,其中包含了我所需的所有信息,包括对th3pat3I答案的进一步扩展。 - bdristan
1
@bdristan 在我更新了答案之后,我现在看到 @MateiRadu 为您提供了正确的答案来监听打开/关闭 SearchView。然而,我希望我的答案仍然有所帮助,因为它在某种程度上解释了为什么它不再起作用 :-) - Darwind
@Darwind,你应该在你的答案底部添加我分享的链接,这样对于未来的观众来说,它将成为一个更完整的解决方案,如果bdristan想将其标记为已接受的答案。 - Matei Radu
1
@MateiRadu,我刚刚做了 - 至少对于完整性有所帮助 - 阅读答案时感觉缺少理解是非常恼人的事情;-) - Darwind
5个回答

48

看了你问题的标题,你不确定如何检测SearchView何时被关闭,因此当SearchView不再打开时无法恢复视图到“正常”状态。

自Android 4.0以后已经过时的解决方案

(简单)的解决方法是将SearchView.OnCloseListener添加到您的SearchView中:

SearchView.setOnCloseListener(new SearchView.OnCloseListener() {
    @Override
    public boolean onClose() {
        // This is where you can be notified when the `SearchView` is closed
        // and change your views you see fit.
    }
});

编辑:

更新的解决方案适用于Android 4.0及以上版本

显然,OnCloseListener存在缺陷,在较新版本的Android(4.0+)上无法正常工作。请参见:https://code.google.com/p/android/issues/detail?id=25758

解决此问题的方法是使用Support库版本的SearchView

我的onCreateOptionsMenu如下所示:

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

    MenuItem searchMenuItem = menu.findItem(R.id.searchView);
    SearchView searchView = (SearchView) searchMenuItem.getActionView();

    MenuItemCompat.setOnActionExpandListener(searchMenuItem, new MenuItemCompat.OnActionExpandListener() {
        @Override
        public boolean onMenuItemActionExpand(MenuItem item) {
            Toast.makeText(ScrollingActivity.this, "onMenuItemActionExpand called", Toast.LENGTH_SHORT).show();
            return true;
        }

        @Override
        public boolean onMenuItemActionCollapse(MenuItem item) {
            Toast.makeText(ScrollingActivity.this, "onMenutItemActionCollapse called", Toast.LENGTH_SHORT).show();
            return true;
        }
    });
}

至于为什么Google甚至都没有在文档中写一条评论,我不知道,但这很令人沮丧。

编辑2:

只是添加@MateiRadu在评论中添加的链接:

如何处理Android中搜索视图的后退按钮

这也展示了如何使用OnActionExpandListener而不是OnCloseListener

希望这可以帮到你。


遗憾的是,当SearchView关闭时,onClose()未被调用。然而,像th3pat3l建议的那样,onQueryTextSubmit()和onQueryTextChange()被调用。理想情况下,我想利用这三个监听器。 - bdristan
如果您有自己的SearchView自定义类,请使用:
@Override public void onActionViewCollapsed() { super.onActionViewCollapsed(); }
- Mike6679
MenuItemCompat现已过时。 请尝试使用MenuItem.setOnActionExpandListener(); https://developer.android.com/reference/android/view/MenuItem.OnActionExpandListener.html - anoo_radha
MenuItemCompat.setOnActionExpandListener()已被弃用。解决方案: https://dev59.com/mVUM5IYBdhLWcg3wWvDF - Johnny Five

11

这里的所有代码都已过时!您应该使用类似于这样的东西。

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

item.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {

            @Override
            public boolean onMenuItemActionExpand(MenuItem item) {
                Toast.makeText(getActivity(), "onMenuItemActionExpand called", Toast.LENGTH_SHORT).show();
                return true;
            }

            @Override
            public boolean onMenuItemActionCollapse(MenuItem item) {
                Toast.makeText(getActivity(), "onMenutItemActionCollapse called", Toast.LENGTH_SHORT).show();
                return true;
            }
        });

希望那能有所帮助。


4

Darwind的答案可以解决问题,但只有当用户按下返回按钮关闭键盘并且SearchView不再具有焦点时才有效。

更好的方法是监听SearchView的文本更改。
这样您可以在文本更新时恢复视图并控制UI。
以下是我的做法。

SearchView searchView = new SearchView(context);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
    @Override
    public boolean onQueryTextSubmit(String query) {
        // this is when user is done typing and clicks search
        return false;
    }

    @Override
    public boolean onQueryTextChange(String newText) {
        // you can use this to do a "live" search while the user is typing.
        // this will trigger each time user changes (adds or removes) text
        // so when newText is empty, restore your views
        return false;
    }
});

4
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main_menu, menu);
    MenuItem searchItem = menu.findItem(R.id.action_search);
    searchView = (SearchView) MenuItemCompat.getActionView(searchItem);

  
    searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean newViewFocus) {
            if (!newViewFocus) {
                //Collapse the action item.
                searchItem.collapseActionView();
                //Clear the filter/search query.
                myFilterFunction("");
            }
        }
    });

    return super.onCreateOptionsMenu(menu);
}

使用它,它很有帮助。 - Rohit Bansal

-1

还有一个技巧:

searchView.setOnSearchViewListener(new MaterialSearchView.SearchViewListener() {
                @Override
                public void onSearchViewShown() {
                    if(!txtToolbarTitle.getText().toString().isEmpty()){
                        searchView.setQuery(txtToolbarTitle.getText().toString()+ " ", false);
                    }
                }

                @Override
                public void onSearchViewClosed() {
                    if(txtToolbarTitle.getText().toString().isEmpty()){
                        finish();
                    }
                }
            });

这是来自一个库的SearchView,而不是Android原生的SearchView。 - Raykud

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接