0

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"/>
Zain
  • 37,492
  • 7
  • 60
  • 84
Merlin1896
  • 1,751
  • 24
  • 39

4 Answers4

2

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.

Vikram
  • 51,313
  • 11
  • 93
  • 122
  • I really hoped this would work because I love how you described the situation. Albeit, it turns out that my searchView only has one child - which to my utter surprise is an android.widget.LinearLayout! I have no idea why that is. – Merlin1896 Nov 25 '15 at 08:56
  • @Merlin1896 Thanks. Wrote the code without testing it :(. Thing is, we'll have to recursively check all children inside `SearchView`. This means, if we find a `ViewGoup` (capable of holding `Views`) - in this case, a `LinearLayout` - we traverse through _its_ children. I'll make an edit for you to test. The change will happen inside `OpenSearchSuggestionsList()`. – Vikram Nov 25 '15 at 12:52
  • Brilliant! That works! Can you explain why a LinearLayout can be a _child_ of a searchview? And one pedantic comment: in the line `OpenSearchSuggestionsList(child);` you forgot to cast the child into a ViewGroup. – Merlin1896 Nov 25 '15 at 13:13
  • @Merlin1896 Sorry. Fixed. – Vikram Nov 25 '15 at 13:15
  • @Merlin1896 `Can you explain why a LinearLayout can be a child of a searchview?` Do you mind if I explain that a bit later in the day? Its time for me to go to work, :). – Vikram Nov 25 '15 at 13:16
  • Just a brief reminder that you wanted to answer this last question I had :) – Merlin1896 Dec 01 '15 at 15:53
  • @Merlin1896 I am _very_ sorry about the delay. I did try to write up an answer to your question. But, I believe it would be more beneficial to you if we could have a quick chat session. Unfortunately, it will have to be over the weekend: F, Sa, Su. I will leave the link to a private StackOverflow chatroom day after tomorrow. Again, I apologize for the delay. – Vikram Dec 09 '15 at 05:14
  • @Merlin1896 I have created a chatroom for our discussion. Please follow this link: [Chatroom](http://chat.stackoverflow.com/rooms/97680/how-to-open-list-of-search-suggestions-programatically). – Vikram Dec 11 '15 at 20:21
1

this will help, Note use the R from app appcompat library import android.support.v7.appcompat.R

mQueryTextView = (AutoCompleteTextView) searchView.findViewById(R.id.search_src_text);

mQueryTextView.showDropDown()
Sam
  • 6,215
  • 9
  • 71
  • 90
1

The accepted answer is a great answer and lead me to another simple answer that may benefit someone else:

private void OpenSearchSuggestionsList() {
    int autoCompleteTextViewID = getResources().getIdentifier("search_src_text", "id", getPackageName());
    AutoCompleteTextView  searchAutoCompleteTextView = searchView.findViewById(autoCompleteTextViewID);
    searchAutoCompleteTextView.showDropDown();
}
Zain
  • 37,492
  • 7
  • 60
  • 84
0

In your search view there is one override method called onQueryTextSubmit you can first try to just return false from this method.

If the above does not work than try this,

@Override
  public boolean onQueryTextSubmit(String query) {

      InputMethodManager inputManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
      inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
      return false;
  }

Hope this helps :)

Hardik Chauhan
  • 2,750
  • 15
  • 30
  • Sorry, this does not help :( The suggestion list still closes – Merlin1896 Nov 21 '15 at 19:54
  • I added some code snippets, see my edit. The database structure is highly based on the "Searchable Dictionary" Example: https://github.com/android/platform_development/blob/master/samples/SearchableDictionary/src/com/example/android/searchabledict/SearchableDictionary.java – Merlin1896 Nov 21 '15 at 20:20
  • Can you add this searchable view? cause i m not able to find it. – Hardik Chauhan Nov 21 '15 at 20:39
  • I added they layout xml part. Not sure what you are specifically asking for. That are all the mentions of the searchview. The searchview is part of the AddTeam class. It is not build into the action bar but rather a standalone field. – Merlin1896 Nov 22 '15 at 00:48