I have a SearchView
in my Android application which can show suggestions to the given input. Now I want the following behaviour: If I finish the keyboard input and press the "enter" button on the softkeyboard, then I want the keyboard to disappear but the list with the search suggestions should remain.
The behaviour right now is, that if I enter some letters, the suggestions appear (good!) but if I am done and press enter, the list disappears (bad!).
So how can I reopen the list but leave the keyboard hidden?
Usually, the intent ACTION_SEARCH is fired and is handled in a way that a new activity opens and shows the search results. I only want the list with suggestions to be opened.
Some of the source code:
In the onCreate() of the AddTeam Class:
SearchView searchView= (SearchView) findViewById(R.id.searchView);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
@Override
public boolean onQueryTextSubmit(String s) {
InputMethodManager inputManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
return false;
}
@Override
public boolean onQueryTextChange(String s) {
return false;
}
});
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
Intent Handling:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
// handles a click on a search suggestion; launches activity to show word
Uri uri = intent.getData();
Cursor cursor = managedQuery(uri, null, null, null, null);
if (cursor == null) {
finish();
} else {
cursor.moveToFirst();
doMoreCode();
}
} else if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
// handles a search query
String query = intent.getStringExtra(SearchManager.QUERY);
//////////////////////////////////////////////////////
//WANTED FEATURE!
OpenSearchSuggestionsList();
//WANTED FEATURE!
//////////////////////////////////////////////////////
}
}
Manifest:
<activity
android:name=".AddTeam"
android:configChanges="keyboard|screenSize|orientation"
android:label="@string/title_activity_teamchooser"
android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
</activity>
Searchable:
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/title_activity_settings"
android:hint="@string/search_hint"
android:searchSettingsDescription="Enter Word"
android:searchSuggestAuthority="com.mypackage.DataProvider"
android:searchSuggestIntentAction="android.intent.action.VIEW"
android:searchSuggestIntentData="content://com.mypackage.DataProvider/teamdaten"
android:searchSuggestSelection=" ?"
android:searchSuggestThreshold="1"
android:includeInGlobalSearch="true"
>
</searchable>
Part of AddTeam Layout xml:
<android.support.v7.widget.SearchView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textColor="#000000"
volleyballinfo:iconifiedByDefault="false"
volleyballinfo:queryHint="@string/search_hint"/>
Note: My answer is only based on source code inspection, and may not produce positive/favorable results. Also, the code below is written from memory - it may contain typos.
Ok. Internally, SearchView
uses a custom AutoCompleteTextView
to display suggestions. This custom AutoCompleteTextView
listens for the submit event through multiple channels: View.OnKeyListener
, overridden SearchView#onKeyDown(int, KeyEvent)
and OnEditorActionListener
.
On a submit event (when the ENTER
key is pressed - in your case), the suggestions-popup is dismissed using SearchView#dismissSuggestions
:
private void dismissSuggestions() {
mSearchSrcTextView.dismissDropDown();
}
As you can see, SearchView#dismissSuggestions()
calls to AutoCompleteTextView#dismissDropDown()
. So, to show the dropdown, we should be able to call AutoCompleteTextView#showDropDown()
.
But, the custom AutoCompleteTextView
instance used by the SearchView
is private with no accessors defined. In this case, we can try to find this View
, cast it to AutoCompleteTextView
, and call showDropDown()
on it.
....
// Your snippet
else if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
// handles a search query
String query = intent.getStringExtra(SearchManager.QUERY);
OpenSearchSuggestionsList(searchView);
}
....
// Edited
// This method will accept the `SearchView` and traverse through
// all of its children. If an `AutoCompleteTextView` is found,
// `showDropDown()` will be called on it.
private void OpenSearchSuggestionsList(ViewGroup viewGroup) {
for (int i = 0; i < viewGroup.getChildCount(); i++) {
View child = viewGroup.getChildAt(i);
if (child instanceof ViewGroup) {
OpenSearchSuggestionsList((ViewGroup)child);
} else if (child instanceof AutoCompleteTextView) {
// Found the right child - show dropdown
((AutoCompleteTextView)child).showDropDown();
break; // We're done
}
}
}
Looking forward to your comment(s) on this.