android – SearchView hints not showing for single character typed-ThrowExceptions

Exception or error:

I’m working on an Android application written in Scala that uses android.support.v7.widget.SearchView inside the action bar that’s overridden by android.support.v7.widget.Toolbar.

In the app, I need to enable search suggestions for that SearchView. So, every time I detect a query change, I check to see if suggestions need to be updated (code below). If the suggestions need to be updated a call is made to the backend and an android.database.MatrixCursor is created that contains the search suggestions and is set on the SearchViews suggestions adapter (code below).

The problem that I’m having with this is that the search hints will not show up when typing a single character. Typing two or more characters in the search box works perfectly.

I’ve tried with android:searchSuggestThreshold set to 0 and 1 in my XML config and I get the same result (like that option being ignored): search hints showing for multiple input characters, but not showing for a single character.

Am I missing something in the config/initialisation of the SearchView? Like an option other than android:searchSuggestThreshold which I can set? I’ve spent the last few hours on looking for alternative options but couldn’t find any.

A possible solution that I see would be getting the AutoCompleteTextView backing the SearchView‘s input and setting the threshold for it to 1, but it’s an ugly (hack-ish) solution as the AutoCompleteTextView is not exposed by the SearchViews API.

Does anyone know an elegant solution for this?

Thank you!

Detecting search term changes:

//this gets called whenever something is changed in the search box. "s" contains the entire search term typed in the search box
def onQueryTextChange(s: String): Boolean = {
  //this checks to see if a call should be made to the backend to update suggestions
  SearchSuggestionController.query(s) 
  //return false as we're not consuming the event
  false
}

Updating search suggestions:

def updateSuggestions(suggestions: Array[String]): Unit = {
  val cursor = new MatrixCursor(Array(BaseColumns._ID, SearchManager.SUGGEST_COLUMN_TEXT_1), suggestions.length)
  for{
    i <- suggestions.indices
    s = suggestions(i)
  } cursor.addRow(Array[AnyRef](i.toString, s))

  getActivity.runOnUiThread(() => {
    searchSuggestionAdapter.changeCursor(cursor)
    searchSuggestionAdapter.notifyDataSetChanged()
  })
}

Menu SearchView initialization:

override def onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) = {
    inflater.inflate(R.menu.menu_products, menu)
    val searchManager = getActivity.getSystemService(Context.SEARCH_SERVICE).asInstanceOf[SearchManager]
    val actionItem = menu.findItem(R.id.action_search)
    searchView = MenuItemCompat.getActionView(actionItem).asInstanceOf[SearchView]
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity.getComponentName))
    searchView.setSubmitButtonEnabled(false)
    SearchSuggestionController.onSuggestionsProvided_=(updateSuggestions)
    searchView setSuggestionsAdapter searchSuggestionAdapter
    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { 
      //...
      //change listener for detecting search changes presented above
      //...
    }
  //...
  //initialise other components 
  //...
}

Searchable config:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_name"
    android:hint="@string/actionbar_products_search_hint"
    android:searchSuggestThreshold="0"
    android:searchSuggestSelection=" ?"/>
How to solve:

You must get handle to the SearchAutoComplete object which SearchView object using, then pragmatically set its threshold to 1.(if your try to set it to 0 it will become 1 it is implemented like that behind the scenes) unfortunately it wont work from XML for some reason.

SearchView.SearchAutoComplete mSearchSrcTextView = (SearchView.SearchAutoComplete) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
// show results from 1 char
mSearchSrcTextView.setThreshold(1);

###

I see your point about “elegant solution” here which is very nice but I’m afraid Android API will force you many times to do “unelegant” anyway if you want to achieve your goals:)

I don’t know workaround with setting threshold directly on AutoCompleteTextView works but if it doesn’t I suggest you to do one (not very nice) step more which might work:

Get instance of EditText:

AutoCompleteTextView searchText = (AutoCompleteTextView) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);

And force to show suggestions in onQueryTextChange for length of text equals 1:

if(s.length() == 1){
   searchText.showDropDown();
{

###

Set an OnQueryTextListener onto your SearchView. Utilize its onQueryTextChange to update your adapter.

Leave a Reply

Your email address will not be published. Required fields are marked *