如何捕捉 SearchView 的清晰按钮单击?

我如何捕捉用户点击清除 SearchView文本的事件,通过点击右边的 X 按钮

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

69722 次浏览

在尝试了许多组合之后,我发现了如何在 SearchView 中捕获 X 按钮后面的事件

下面是我的一个应用程序中 onCreateOptionsMenu函数的代码片段。 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);
}

我在试图通过组件的 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.
}
});

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

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

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

如果使用 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

    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 作为“ Submit”按钮

Kotlin 的回答是:

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

来自 爱德华多的解决方案对我不起作用。我发现了一些对 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
}

如果你正在使用来自 androidx 的 SearchView,你可以这样做:

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

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

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

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

mySearchView.setOnCloseListener {
// Do your stuff
return false
}

我通过检查 androidx.appcompat.widget.SearchView类和 id 关闭按钮得到了这个答案,并找到了 ImageView mCloseButton = findViewById(R.id.search_close_btn);。因此,解决方案是在 searchView 实现中获取这个 id 的引用,并将 onClickListener 附加到它。因此,在内部发生的是,我们正在覆盖 imageView 的 setOnClickListener 并添加我们的实现。这是密码。

SearchView searchView = findViewById(R.id.search_view);
ImageView closeButton = searchView.findViewById(R.id.search_close_btn);
if (closeButton != null) closeButton.setOnClickListener(v -> {
//your logic goes in here
});