I'm currently using ActionBarSherlock 4.2 and it's SearchView widget in my app.
I wanted to make it submit query even though it's empty. I tried to set imeOptions and OnKeyListener but both were ignored without a reason.
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
Log.d(TAG, "onCreateOptionsMenu");
inflater.inflate(R.menu.interactive_map, menu);
mSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
mSearchView.setImeOptions(EditorInfo.IME_ACTION_GO);
mSearchView.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
Log.d(TAG, "keyCode: " + keyCode);
Log.d(TAG, "Action: " + event.getAction());
if(keyCode == EditorInfo.IME_ACTION_SEARCH){
onQueryTextSubmit(""+mSearchView.getQuery());
}
return false;
}
});
super.onCreateOptionsMenu(menu, inflater);
}
onKey's never get triggered as both Logcat entries never appear in Logcat window. Not sure if this being inside SherlockFragment is the problem.
Nothing special's done to the menu item as well.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/action_search"
android:title="#string/app_name"
android:icon="#android:drawable/ic_menu_search"
android:showAsAction="always"
android:actionViewClass="com.actionbarsherlock.widget.SearchView" />
</menu>
Is there a way to get around this? Or is there simpler way to enable submitting when query is empty? It doesn't seems to support any configuration in the source code though.
I switched to put SearchView via ActionMode instead. I'll accept this as an answer for now until someone has a better solution for this question.
private void showActionMode(){
MainActivity a = (MainActivity)getActivity();
a.startActionMode(new SearchActionMode());
}
private class SearchActionMode implements ActionMode.Callback{
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
Log.d(TAG, "onCreateActionMode creating inflater");
MenuInflater inflater = new MenuInflater(getActivity());
Log.d(TAG, "onCreateActionMode inflating");
inflater.inflate(R.menu.interactive_map, menu);
Log.d(TAG, "onCreateActionMode finding SearchView");
mSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
Log.d(TAG, "mSearchView: " + mSearchView);
setupSearchView();
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
Log.d(TAG, "onPrepareActionMode");
//TODO add searchView once working
mSearchView.requestFocus();
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
Log.d(TAG, "onActionItemClicked");
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
Log.d(TAG, "onDestroyActionMode");
closeTopTray();
closeListView();
}
}
private void setupSearchView() {
mSearchView.setIconifiedByDefault(false);
mSearchView.setId(ID_SEARCH_VIEW);
mSearchView.setOnSearchClickListener(this);
mSearchView.setOnQueryTextListener(this);
mSearchView.setOnCloseListener(this);
mSearchView.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
// To automatically display keyboard when display SearchView
mSearchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
Log.d(TAG, "mSearchView focus changed: " + hasFocus);
if (hasFocus) {
showInputMethod(v.findFocus());
}
}
});
mSearchView.setQueryHint("Type keyword");
mSearchView.setQuery((TextUtils.isEmpty(searchQuery)? "": searchQuery), false);
}
I had the same problem, the problem lies onSubmitQuery() in SearchView.java
private void onSubmitQuery() {
CharSequence query = mQueryTextView.getText();
if (query != null && TextUtils.getTrimmedLength(query) > 0) {
Empty query's are not supported so I had to download and use ActionBarSherlock and then modify this method.
This is how my onSubmitQuery() looks like now
private void onSubmitQuery() {
CharSequence query = mQueryTextView.getText();
if (query == null) {query = "";}
if (mOnQueryChangeListener == null
|| !mOnQueryChangeListener.onQueryTextSubmit(query.toString())) {
if (mSearchable != null) {
launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null, query.toString());
setImeVisibility(false);
}
dismissSuggestions();
}
}
Hope this helps.
Related
I have implemented SearchView in ActionBar, But the problem with it is, whenever am typing something and press submit, the SearchView doesn't collapse back into that Search icon, it stays expanded, neither when I press Back button, SearchView doesn't collapse back.
My implementation is like this:
menu_search.xml
<item
android:id="#+id/app_bar_search"
android:icon="#drawable/ic_search_white_24dp"
android:title="Search"
app:actionViewClass="android.widget.SearchView"
app:showAsAction="always" />
MainActivity.java
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_search, menu);
item = menu.findItem(R.id.app_bar_search);
searchView = (SearchView) item.getActionView();
searchView.setMaxWidth(Integer.MAX_VALUE);
int searchBarId = searchView.getContext().getResources().getIdentifier("android:id/search_bar", null, null);
searchBar = searchView.findViewById(searchBarId);
searchBar.setLayoutTransition(new LayoutTransition());
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
item.collapseActionView();
searchView.setQuery("", false);
searchView.clearFocus();
searchBar.clearFocus();
.
.
.
.
.
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
Things I have tried:
#Override
public void onBackPressed() {
super.onBackPressed();
if (item.isActionViewExpanded()) {
item.collapseActionView();
} else {
super.onBackPressed();
}
}
and
#Override
public void onBackPressed() {
super.onBackPressed();
if (searchView != null) {
searchView.onActionViewCollapsed();
searchView.setQuery("", false);
searchView.clearFocus();
searchBar.clearFocus();
hideSoftKeyboard(MainActivity.this);
} else {
super.onBackPressed();
}
}
public static void hideSoftKeyboard(Activity activity) {
InputMethodManager inputMethodManager =
(InputMethodManager) activity.getSystemService(
Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(
activity.getCurrentFocus().getWindowToken(), 0);
}
SearchView expands from left to right to type but doesn't collapse back form right to left.
Please advice.
Try below code and let me know if it works.
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(new ComponentName(this, ResultActivity.class)));
searchView.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() {
#Override
public boolean onSuggestionSelect(int position) {
return false;
}
#Override
public boolean onSuggestionClick(int position) {
searchView.clearFocus();
item.collapseActionView();
return false;
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
searchView.clearFocus();
item.collapseActionView();
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
I was going through the second page of Google search and found this.
It worked for me.
searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
searchView.setIconified(true);
}
}
});
I have implemented searchview in actionbar and it is working fine. In viewpager if user switch between fragment I want to keep the state of searchview, to do so whenever fragment switch I applied query and show search result in recycler until now it is working like charm except I want to expand my searchview and put a query into it on fragment change method. I have seen lots of thread on it and I have applied multiple solutions none worked.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_search"
android:icon="#drawable/ic_search_black_24dp"
app:showAsAction="always|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"
android:title="Search"/>
</menu>
In onCreateOptionsMenu i am inflating my menu.
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main2, menu);
this.menu = menu;
searchActionBar(menu);
super.onCreateOptionsMenu(menu, inflater);
}
In search Actionbar i am fetching query result and save query text to mQuery and clear this text when searchview collapse.
private void searchActionBar(Menu menu){
searchViewItem = menu.findItem(R.id.action_search);
searchViewAndroidActionBar = (SearchView) MenuItemCompat.getActionView(searchViewItem);
searchViewAndroidActionBar.setIconifiedByDefault(false);
searchViewAndroidActionBar.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#SuppressLint("RestrictedApi")
#Override
public boolean onQueryTextSubmit(String query) {
searchViewAndroidActionBar.clearFocus();
mQuery = query;
fetchSearchResult(query);
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
return true;
}
});
MenuItemCompat.setOnActionExpandListener(searchViewItem, new MenuItemCompat.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
mQuery="";
return true;
}
});
}
This function is called when fragment switch in viewpager , if there is any query I want to set in searchview. But searchview doesn't expand. Although query submit function is running.
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isResumed() && isVisibleToUser) {
if (searchViewAndroidActionBar != null) {
searchViewAndroidActionBar.setFocusable(true);
searchViewAndroidActionBar.setQuery(mQuery,true);
}
}
}
Any help would be appreciated.
Background
I have a searchView being initialized using a special class I've made, that's being used across all of the activities and fragments.
The problem
Recently, probably due to updates to the support library (or because I didn't use it so far, I don't remember), I can't catch events of expand/collapse of the searchView.
As I've found, this happens even if I use setSupportActionBar with a Toolbar instance.
What I've tried
I've tried using each of the next methods, but none worked:
MenuItemCompat.setOnActionExpandListener.
MenuItemCompat.setOnActionExpandListener together with iconifying the SearchView, as suggested on some websites.
setOnActionExpandListener on the search menu item itself, but then it crashes since it can't be used when extending the ActionBarActivity.
SearchView.setOnCloseListener , but this works only if I close it, and only using the UI (doesn't get called when calling collapseActionView ).
I've also tried to mess around with the XML file of the search menu item.
The code
Here's the helper class I've made:
SearchHolderCompat
public class SearchHolderCompat {
public MenuItem mSearchMenuItem;
public SearchView mSearchView;
private final Activity _context;
public SearchHolderCompat(final Activity context) {
_context = context;
}
public boolean isCurrentyExpanded() {
return mSearchMenuItem != null && MenuItemCompat.isActionViewExpanded(mSearchMenuItem);
}
public boolean hasQuery() {
return mSearchMenuItem != null && mSearchView != null && MenuItemCompat.isActionViewExpanded(mSearchMenuItem)
&& !TextUtils.isEmpty(mSearchView.getQuery());
}
public void addSearchItemAndInit(final Menu menu, final OnQueryTextListener onQueryTextListener,
final OnActionExpandListener onActionExpandListener) {
final MenuInflater menuInflater = _context.getMenuInflater();
menuInflater.inflate(R.menu.search_menu_item, menu);
init(menu.findItem(R.id.menuItem_search), onQueryTextListener, onActionExpandListener);
}
public void init(final MenuItem searchMenuItem, final OnQueryTextListener onQueryTextListener,
final OnActionExpandListener onActionExpandListener) {
this.mSearchMenuItem = searchMenuItem;
mSearchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
if (mSearchView == null) {
MenuItemCompat.setShowAsAction(searchMenuItem, MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
| MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
MenuItemCompat.setActionView(searchMenuItem, mSearchView = new SearchView(_context));
}
mSearchView.setQueryHint(_context.getString(R.string.search));
mSearchView.setOnQueryTextListener(onQueryTextListener);
MenuItemCompat.setOnActionExpandListener(searchMenuItem, onActionExpandListener);
}
}
MainActivity.java
public class MainActivity extends ActionBarActivity {
SearchHolderCompat mSearchHolder = new SearchHolderCompat(this);
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
mSearchHolder.addSearchItemAndInit(menu, new OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(final String arg0) {
android.util.Log.d("AppLog", "onQueryTextSubmit");
return false;
}
#Override
public boolean onQueryTextChange(final String queryText) {
android.util.Log.d("AppLog", "onQueryTextChange");
return true;
}
}, new OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(final MenuItem arg0) {
android.util.Log.d("AppLog", "onMenuItemActionExpand");
return false;
}
#Override
public boolean onMenuItemActionCollapse(final MenuItem arg0) {
android.util.Log.d("AppLog", "onMenuItemActionCollapse");
return false;
}
});
return true;
}
}
search_menu_item.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<!-- search items -->
<item
android:id="#+id/menuItem_search"
android:icon="#drawable/ic_action_search"
android:title="#string/search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always"
tools:ignore="AlwaysShowAction"/>
</menu>
The question
What's the correct way to handle the SearchView and the search menu item (using the support library) ?
How come "MenuItemCompat.setOnActionExpandListener" doesn't work?
After looking for a solution for couple of hours I've implement something like this. and worked for me. (I wanted Expand and Collapse events anyhow)
.
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.menu_main, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
if(searchItem != null)
{
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
// use this method for search process
searchView.setOnSearchClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//Search view is expanded
showSearchPage();
}
});
searchView.setOnCloseListener(new SearchView.OnCloseListener()
{
#Override
public boolean onClose()
{
//Search View is collapsed
hideSearchPage();
return false;
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener()
{
#Override
public boolean onQueryTextSubmit(String query)
{
// use this method when query submitted
Toast.makeText(MainActivity.this, query, Toast.LENGTH_SHORT).show();
return false;
}
#Override
public boolean onQueryTextChange(String newText)
{
// use this method for auto complete search process
Log.e("SearchValueIs",":"+newText);
return false;
}
});
}
return super.onCreateOptionsMenu(menu);
}
Hope It will help Someone...
Android training
app:showAsAction="ifRoom|collapseActionView"
You can add ViewTreeObserver to track the visibility state of android.support.v7.appcompat.R.id.search_edit_frame. You can check my answer here: https://stackoverflow.com/a/28762632/1633609
You can see below how to handle Expand and Collapsed states!
To answer why MenuItemCompat.setOnActionExpandListener(...) is not working, this listener is only called if the showAsAction of the SearchView is set to MenuItemCompat.SHOW_AS_ACTION_ALWAYS (you can also add more options).
This is the copy of my answer form the other question:
I found that MenuItemCompat.setOnActionExpandListener(...) is not working if you don't pass:
searchItem
.setShowAsAction(MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
| MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
But this is changing the SearchView and is replacing the DrawerToggle with back arrow.
I wanted to keep the original views and still track the Expanded/Collapsed state and use supported Search View.
Solution:
When android.support.v7.widget.SearchView is changing the view state the LinearLayout view's, with id android.support.v7.appcompat.R.id.search_edit_frame, visibility value is being changed from View.VISIBLE to View.GONE and opposite. So I add ViewTreeObserver to track the visibility change of the search edit frame.
menu_search.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item
android:id="#+id/action_search"
android:icon="#android:drawable/ic_menu_search"
android:title="#string/search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always"/>
</menu>
In the activity:
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.SearchView;
import android.view.Menu;
import android.view.MenuItem;
..........
private View mSearchEditFrame;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_search, menu);
MenuItem searchItem = (MenuItem) menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat
.getActionView(searchItem);
searchView.setSubmitButtonEnabled(false);
mSearchEditFrame = searchView
.findViewById(android.support.v7.appcompat.R.id.search_edit_frame);
ViewTreeObserver vto = mSearchEditFrame.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
int oldVisibility = -1;
#Override
public void onGlobalLayout() {
int currentVisibility = mSearchEditFrame.getVisibility();
if (currentVisibility != oldVisibility) {
if (currentVisibility == View.VISIBLE) {
Log.v(TAG, "EXPANDED");
} else {
Log.v(TAG, "COLLAPSED");
}
oldVisibility = currentVisibility;
}
}
});
return super.onCreateOptionsMenu(menu);
}
I know I'm very late to post this answer but hope it helps someone else. I recently came across the issue and I just made the Override methods return true and it worked like a charm.
#Override
public boolean onMenuItemActionExpand(final MenuItem arg0) {
android.util.Log.d("AppLog", "onMenuItemActionExpand");
return true;
}
#Override
public boolean onMenuItemActionCollapse(final MenuItem arg0) {
android.util.Log.d("AppLog", "onMenuItemActionCollapse");
return true;
}
In more recent versions
menuSearch.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
//SearchView appers
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
//SearchView disappears
return true;
}
});
I have search view in my fragment. when I click on it , keyboard is open and I can type text. I want when I click on search button in keyboard , my query send to my server and get result but I don't know how get search event. any solution?
You have to extend OnQueryTextListener, attach the listener and implement onQueryTextSubmit.
Example:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
searchView = (SearchView) menu.findItem(R.id.mActionSearch).getActionView();
searchView.setOnQueryTextListener(this);
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
//Do something here
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
Pozzo Apps Answer is right
but for api below 11 and compat library you can use something like this :
MenuItem search_menu=(MenuItem)menu.findItem(R.id.action_search);
SearchView searchView =(SearchView)MenuItemCompat.getActionView(search_menu);
You can also apply setOnKeyListener on search view like as below:
searchview.setOnKeyListener(new View.OnKeyListener(
{
Public boolean onKey(View v, int keyCode, KeyEvent event)
{
if(event.getAction() == KeyEvent.ACTION_DOWN)
{
switch(keyCode)
{
Case KeyEvent.KECODE_ENTER:
// Apply action which you want on search key press on keypad
return true;
default:
break;
}
} return false;
}
});
You have to add new OnQueryTextListener, and implement onQueryTextSubmit. This also works in a fragment.
Example:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main_search, menu);
SearchView sv = (SearchView) menu.findItem(R.id.action_search).getActionView();
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
//Do something here
Toast.makeText(getActivity(), "Search: " + query, Toast.LENGTH_SHORT ).show();
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
super.onCreateOptionsMenu(menu,inflater);
}
I am currently using an ActionBar menu item to display a SearchView in the action bar. When the search menu item is expanded the soft keyboard is displayed which is what I want. Now, when the user presses the back button to close the soft keyboard, I would also like to collapse the SearchView in the action bar.
I have tried implementing the following listeners OnKeyListener and OnFocusChangeListener on the MenuItem and the ActionView. I have also tried using OnBackPressed() in the Activity. None of the above detect when the back button is used to close the soft keyboard.
Any ideas?
I have implemented OnActionExpandListener to know when the SearchView is visible.
I'll expand on #user1258568 's answer for the lazy. This worked for me. Note that it clears your query when focus is lost.
final MenuItem searchMenuItem = optionsMenu.findItem(R.id.search);
final SearchView searchView = (SearchView) searchMenuItem.getActionView();
searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean queryTextFocused) {
if(!queryTextFocused) {
searchMenuItem.collapseActionView();
searchView.setQuery("", false);
}
}
});
I found a better solution.
searchView.setOnQueryTextFocusChangeListener().
The OnQueryTextFocusChangeListener gets called when the keyboard is displayed or hidden. Gets called first when the keyboard is displayed and the search view will have focus. Gets called again when keyboard is hidden and search view will lose focus, can close search viewthen using
menuItem.collapseActionView().
Just Override onBackPressed like this:
#Override
public void onBackPressed() {
if (searchView.isShown()){
searchView.onActionViewCollapsed(); //collapse your ActionView
searchView.setQuery("",false); //clears your query without submit
isClosed = true; //needed to handle closed by back
} else{
super.onBackPressed();
}
}
and your onCreateOptionsMenu would inflate the mSearchView like this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_search, menu);
mSearchView = (SearchView) menu.findItem(R.id.menu_action_search).getActionView();
mSearchView.setOnQueryTextListener(this);
mSearchView.setOnSearchClickListener(this);
mSearchView.setOnCloseListener(this);
isClosed = true;
return true;
}
have you class implement the following like this:
public class myActivity extends FragmentActivity implements
SearchView.OnQueryTextListener, View.OnClickListener, SearchView.OnCloseListener {
which you will also need:
#Override
public void onClick(View view) {
isClosed = false;
}
#Override
public boolean onClose() {
isClosed = true;
return false;
}
You will need to make "mSearchView" and "isClosed" both global variables to the activity.
The answer from Jon Willis works great. This is an improvement to his answer.
First, create a new class that implements View.OnFocusChangeListener:
public class SearchViewFocusListener implements View.OnFocusChangeListener {
private final MenuItem mMenuItem;
public SearchViewFocusListener(MenuItem menuItem) {
mMenuItem = menuItem;
}
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
mMenuItem.collapseActionView();
if (v instanceof SearchView) {
((SearchView) v).setQuery("", false);
}
}
}
}
Next, set the listener on your SearchView:
searchView.setOnQueryTextFocusChangeListener(new SearchViewFocusListener(menuItem));
You only need to put the "collapseActionView" attribute in the menu layout
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/menu_item_search"
android:title="#string/search"
android:iconifiedByDefault="true"
android:icon="#drawable/ic_action_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView"/> <--this one
</menu>
That will give you the functionality you look for all by itself.Don't forget to call the method "clearFocus" on the SearchView to close the keyboard once you send the query.
This is what I did for making the keyboard disappear. You can try to see if this works for you. I set the searchView to invisible and then to visible again.
//set query change listener
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
#Override
public boolean onQueryTextChange(String newText) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onQueryTextSubmit(String query) {
/**
* hides and then unhides search tab to make sure keyboard disappears when query is submitted
*/
searchView.setVisibility(View.INVISIBLE);
searchView.setVisibility(View.VISIBLE);
return false;
}
});
It's achievable like this:
private void setupSearchView(Menu menu) {
final MenuItem searchMenuItem = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) searchMenuItem.getActionView();
[...]
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
searchMenuItem.collapseActionView();
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
return true;
}
});
}
Solutions based on setOnQueryTextFocusChangeListener() did not work for me because the event was not launched - the searchView did not lose focus when submitted, probably because I perform the search in the same activity that contains the Search View.
Anyway, I think using OnQueryTextListener is more correct, as it describes the event of submitting text more precisely.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.home_screen, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
final MenuItem searchMenuItem = menu.findItem(R.id.menu_search);
final SearchView searchView = (SearchView) searchMenuItem
.getActionView();
searchView.setIconifiedByDefault(false);
if (searchManager != null && searchView != null) {
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
searchView
.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
if (searchMenuItem != null) {
searchMenuItem.collapseActionView();
}// end if
if (searchView != null) {
searchView.setQuery("", false);
}// end if
}// end if
}
});
searchView
.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
/**
* hides and then unhides search tab to make sure
* keyboard disappears when query is submitted
*/
if (searchView != null) {
searchView.setVisibility(View.INVISIBLE);
searchView.setVisibility(View.VISIBLE);
}
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
// TODO Auto-generated method stub
return false;
}
});
}
return super.onCreateOptionsMenu(menu);
}
If you want to collapse keyboard when user clicks search icon on keyboard
this can be achieved by simple
inside onquerytextsubmitted {
searchView.clearfocus()
}
You need to call setIconified twice.
To actually collapse your search view and close the keyboard.
With first call text of search view is cleared with second call keyboard and search view get closed.
For some reason, menuItem.collapseActionView() did not work so I used searchView.setIconified(true) instead.
This gives the below result as the code sample.
final MenuItem searchItem = (MenuItem) menu.findItem(R.id.menu_item_search);
final SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setOnQueryTextFocusChangeListener(new SearchView.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
searchView.setIconified(true);
}
}
});