Android Searchview : Open suggestions list dropdown by default

Viewed 2385

The following code allows to display a small suggestion window in my searchview :

enter image description here

I'm searching a way to display this view at the beginning by default when the user click on the search item on the menu.

Is there any way to force this behavior ?

val from = arrayOf(SearchManager.SUGGEST_COLUMN_TEXT_1)
        val to = intArrayOf(R.id.item_label)
        val cursorAdapter = SimpleCursorAdapter(context, R.layout.search_item, null, from, to, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER)
        val suggestions = listOf("Apple", "Blueberry", "Carrot", "Daikon")

        searchView.suggestionsAdapter = cursorAdapter

        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(query: String?): Boolean {
                hideKeyboard()
                return false
            }

            override fun onQueryTextChange(query: String?): Boolean {
                val cursor = MatrixCursor(arrayOf(BaseColumns._ID, SearchManager.SUGGEST_COLUMN_TEXT_1))

                query?.let {
                    suggestions.forEachIndexed { index, suggestion ->
                        if (suggestion.contains(query, true)) {
                            cursor.addRow(arrayOf(index, suggestion))
                        }
                    }
                }

                cursorAdapter.changeCursor(cursor)
                return true
            }
        })

        searchView.setOnSuggestionListener(object: SearchView.OnSuggestionListener {
            override fun onSuggestionSelect(position: Int): Boolean {
                return false
            }

            override fun onSuggestionClick(position: Int): Boolean {
                hideKeyboard()
                val cursor = searchView.suggestionsAdapter.getItem(position) as Cursor
                val selection = cursor.getString(cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1))
                searchView.setQuery(selection, false)

                // Do something with selection
                return true
            }
        })
2 Answers

Solution

Case 1: The SearchView does not expand, users must click on the search button to enter search text.

Put it together.

val searchSrcTextView 
        = searchView.findViewById<AutoCompleteTextView>(R.id.search_src_text)
        
// Set the threshold to 0
searchSrcTextView.threshold = 0

// Listen event when users click on the search view
searchView.setOnSearchClickListener {
    // Fill data to the cursor
    val cursor = MatrixCursor(arrayOf(BaseColumns._ID, SearchManager.SUGGEST_COLUMN_TEXT_1))
    suggestions.forEachIndexed { index, suggestion ->
        cursor.addRow(arrayOf(index, suggestion))
    }
    cursorAdapter.changeCursor(cursor)

    // Show suggestions drop down view
    searchSrcTextView.showDropDown()
}

Case 2: The SearchView expands if users call onActionViewExpanded() method at initial state.

val searchSrcTextView
        = searchView.findViewById<AutoCompleteTextView>(R.id.search_src_text)

// Set the threshold to 0
searchSrcTextView.threshold = 0

// Fill data to the cursor
val cursor = MatrixCursor(arrayOf(BaseColumns._ID, SearchManager.SUGGEST_COLUMN_TEXT_1))
suggestions.forEachIndexed { index, suggestion ->
    cursor.addRow(arrayOf(index, suggestion))
}
cursorAdapter.changeCursor(cursor)
searchView.onActionViewExpanded()

// Show suggestions drop down view
searchSrcTextView.post { 
    searchSrcTextView.showDropDown()
}

In both cases, when users click on the SearchView, the suggestions drop down will display. If users search some text then clear search text by clicking on the close search button or press the CLEAR key on the keyboard, the suggestions still display on screen. To avoid this behavior you can use setThreshold(int) to set SearchView's threshold.

  • Set to 0 at the initial state or when users click on the search button

  • Set to an expected value in onQueryTextChange(String).

Example

searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
    override fun onQueryTextSubmit(query: String?): Boolean {
        hideKeyboard()
        return false
    }

    override fun onQueryTextChange(query: String?): Boolean {
        // Add this code to set threshold to expected value
        if (query?.isEmpty() == true) {
            searchSrcTextView.threshold = 1
        }

        val cursor = MatrixCursor(arrayOf(BaseColumns._ID, SearchManager.SUGGEST_COLUMN_TEXT_1))

        query?.let {
            suggestions.forEachIndexed { index, suggestion ->
                if (suggestion.contains(query, true)) {
                    cursor.addRow(arrayOf(index, suggestion))
                }
            }
        }

        cursorAdapter.changeCursor(cursor)
        return true
    }
})

You can try to do something like adding a click listener on the searchView and if the string in your list contains any letters from a to z, add the result just as to display the whole list.

searchView.setOnClickListener(View.OnClickListener {
    suggestions.forEachIndexed { index, suggestion ->
        if (suggestion.matches("[a-zA-Z]+")) {
            cursor.addRow(arrayOf(index, suggestion))
        }
    }
})
Related