Reputation: 5770
I have a single Activity
app where I put a SearchView
on the topbar. I am struggling since there are like thousands of manuals/tutorials on implementing search online, but all of them seem to be outdated somehow. Even the official documentation does not make it clear for me.
For one reason or the other, I have to use a single Activity
in my app, and handle the whole interaction with Fragment
.
I am struggling on how to make the SearchView
behave like I want to: I want the menu item to show the search bar at the top when i click it, then offer history and suggestions, then whenever something is searched, open a different Fragment
with the results (actually, a TabLayout
with three different result types) -- this is the way Youtube does I think.
I got to the point where searching for something brings another Fragment
to the screen, but then I want that when the user clicks on the back arrow, the user is brought back to the previous Fragment
(without it having to reload again the info -- there is endless scrolling so the user might have loaded tons of data): Whenever I click, first the action view for search disappears, then if I hit back again, the previous Fragment
shows up but it's reloading its content.
this is my setupSearch() method:
private fun setupSearch(menu: Menu) {
// Get the SearchView and set the searchable configuration
val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
val searchItem = menu.findItem(R.id.app_search)
val searchView = searchItem.actionView as SearchView
// Assumes current activity is the searchable activity
searchView.setSearchableInfo(searchManager.getSearchableInfo(componentName))
var searchEditTextId = R.id.search_src_text;
var searchEditText = searchView.findViewById<AutoCompleteTextView>(searchEditTextId)
var dropDownAnchor = searchView.findViewById<View>(searchEditText.dropDownAnchor)
if (dropDownAnchor != null) {
dropDownAnchor.addOnLayoutChangeListener { p0, p1, p2, p3, p4, p5, p6, p7, p8 ->
// screen width
var screenWidthPixel = [email protected]
searchEditText.dropDownWidth = screenWidthPixel
}
}
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
var searchSuggestion = SearchRecentSuggestions(this@DashboardListActivity, SearchHistoryProvider.AUTHORITY, SearchHistoryProvider.MODE)
searchSuggestion.saveRecentQuery(query, null)
supportFragmentManager
.beginTransaction()
.replace(R.id.fragment_container, SearchResultsContainerFragment.newInstance())
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.addToBackStack("SEARCH")
.commit()
return false
}
override fun onQueryTextChange(newText: String): Boolean {
return false
}
})
searchItem.setOnActionExpandListener(object : MenuItem.OnActionExpandListener{
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
return true
}
override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
return true
}
})
searchView.setOnSuggestionListener(object: SearchView.OnSuggestionListener {
override fun onSuggestionSelect(position: Int): Boolean {
return false
}
override fun onSuggestionClick(position: Int): Boolean {
return false
}
})
}
Also, when displaying the suggestion list, it seems the Activity
is somehow paused and resumed (I guess because it is implemented as a dialog
?). This would not be a problem but I am keeping a video window always on top of all views (hence my need to do everything with Fragment
) and the video stops for a split sec then continues. Is it possible to prevent that?
Search seemed like an easy task but its becoming kind of a nightmare. The official documentation says that i must create a different Activity
that is "Searchable" but I cannot do that.
Upvotes: 2
Views: 970
Reputation: 13699
You can use any of these library as per your requirements :
https://github.com/MiguelCatalan/MaterialSearchView
https://github.com/arimorty/floatingsearchview
https://github.com/lapism/SearchView
Upvotes: 0
Reputation: 2065
If you do not want to reload the fragment(that contains the search) when you go back you have to change the replace fragment with add. That is because replace does a remove (of any fragment) followed by an add(the new fragment).
Upvotes: 1