SearchView in Android Toolbar
<!--styling searchview-->
<!--https://philio.me/styling-the-searchview-with-appcompat-v21/-->
<!--changing background color-->
<!--https://stackoverflow.com/questions/27240200/changing-the-background-color-of-searchview-autocomplete-dropdown-->
<style parent="Theme.AppCompat.Light.DarkActionBar" name="AppTheme">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="searchViewStyle">@style/AppTheme.SearchViewStyle</item>
</style>
<style name="AppTheme.SearchViewStyle" parent="Widget.AppCompat.SearchView">
<!-- Gets rid of the search icon -->
<item name="searchIcon">@drawable/ic_search</item>
<!-- Gets rid of the "underline" in the text -->
<item name="queryBackground">@color/colorWhite</item>
<!-- Gets rid of the search icon when the SearchView is expanded -->
<!--<item name="searchHintIcon">@null</item>-->
<!-- The hint text that appears when the user has not typed anything -->
<!--<item name="queryHint">@string/search_hint</item>-->
</style>
<!-- ToolBar -->
<style name="ToolBarStyle" parent="Theme.AppCompat">
<item name="android:textColorPrimary">@android:color/white</item>
<item name="android:textColorSecondary">@android:color/white</item>
<item name="actionMenuTextColor">@android:color/white</item>
<item name="android:dropDownItemStyle">@style/myDropDownItemStyle</item>
<item name="android:dropDownListViewStyle">@style/myDropDownListViewStyle</item>
</style>
<style name="myDropDownItemStyle" parent="Widget.AppCompat.DropDownItem.Spinner">
<item name="android:textColor">@color/secondary_text_default_material_light</item>
<item name="android:textSize">14dp</item>
</style>
<style name="myDropDownListViewStyle" parent="Widget.AppCompat.ListView.DropDown">
<item name="android:background">#FFF</item>
</style>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity"
xmlns:yourapp="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_search"
android:orderInCategory="100"
android:title="@string/action_search"
android:icon="@drawable/ic_search"
yourapp:showAsAction="ifRoom|collapseActionView"
yourapp:actionViewClass="android.support.v7.widget.SearchView" />
</menu>
import android.app.SearchManager
import android.content.Context
import android.database.MatrixCursor
import android.os.Bundle
import android.os.Environment
import android.provider.BaseColumns
import android.support.v4.app.Fragment
import android.support.v4.content.ContextCompat
import android.support.v4.view.MenuItemCompat
import android.support.v4.widget.CursorAdapter
import android.support.v7.widget.SearchView
import android.text.InputType
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.widget.EditText
import us.kostenko.mnemonikon.R
import us.kostenko.mnemonikon.codes.utility.AppConstant
import us.kostenko.mnemonikon.codes.utility.Image
import us.kostenko.mnemonikon.codes.utility.Utils
import java.io.File
import java.util.*
/**
* Created by Admin on 5/30/17.
* Base fragment with search functionality
*/
abstract class BaseSearchableFragment: Fragment() {
lateinit var suggestionAdapter: CursorAdapter
private val SEARCH_TAG = "searchTag"
lateinit var util: Utils
lateinit var images: ArrayList<Image>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
util = Utils(context)
setHasOptionsMenu(true)
}
companion object {
val SUGGESTION_COLUMN_NAME = "suggestion"
val SUGGESTION_COLUMN_PATH = "path"
}
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
// val searchItem = menu?.add(0, search, 0, R.string.action_search)
// searchItem?.setIcon(R.drawable.ic_action_search)
inflater?.inflate(R.menu.menu_search, menu)
val searchItem = menu?.findItem(R.id.search)
val searchView = MenuItemCompat.getActionView(searchItem) as SearchView
// alternatively
// val searchView = SearchView(activity)
// val item = menu.add(Menu.NONE, cMenuItemSearch, Menu.NONE, getString(R.string.menu_search))
// .setActionView(searchView)
// .apply { setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS) }
val searchManager = activity.getSystemService(Context.SEARCH_SERVICE) as SearchManager
// searchView.queryHint = resources.getString(R.string.search_hint)
searchView.setSearchableInfo(searchManager.getSearchableInfo(activity.componentName))
// set hint color
val editText = searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text) as EditText
editText.setHintTextColor(ContextCompat.getColor(activity, R.color.colorText))
editText.inputType = InputType.TYPE_CLASS_NUMBER
// set up hints
suggestionAdapter = SearchAdapter(context, null)
searchView.suggestionsAdapter = suggestionAdapter
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
loadSearchResultsFragment(query)
return false
}
override fun onQueryTextChange(query: String): Boolean {
loadSuggestions(query, suggestionAdapter)
return false
}
})
searchView.setOnSuggestionListener(object : SearchView.OnSuggestionListener {
override fun onSuggestionSelect(position: Int) = false
override fun onSuggestionClick(position: Int): Boolean {
loadSearchResultsFragment(getQueryFromCursor(position))
return false
}
})
MenuItemCompat.setOnActionExpandListener(searchItem, object : MenuItemCompat.OnActionExpandListener {
override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
setItemsVisibility(menu, searchItem, true)
return true
} // Return true to collapse action view
override fun onMenuItemActionExpand(item: MenuItem): Boolean {
setItemsVisibility(menu, searchItem, false)
return true
} // Return true to expand action view
})
}
private fun loadSearchResultsFragment(query: String) {
// val position = images.indexOf(images.first { it.name == query })
// val ft = activity.supportFragmentManager.beginTransaction()
// val newFragment = SlideshowDialogFragment.newInstance(ArrayList(images.map { it.path }), position)
// newFragment.show(ft, "slideshow")
}
private fun getQueryFromCursor(position: Int): String {
var query = ""
val cursor = suggestionAdapter.cursor
if (suggestionAdapter.cursor.moveToPosition(position)) {
query = cursor.getString(cursor.getColumnIndex(SUGGESTION_COLUMN_NAME))
}
return query
}
/** Presenter */
fun loadSuggestions(query: String, adapter: CursorAdapter) {
val c = MatrixCursor(arrayOf(BaseColumns._ID, SUGGESTION_COLUMN_NAME, SUGGESTION_COLUMN_PATH))
val folderName: String
if (query.length == 2) {
folderName = "00--99"
} else {
folderName = "00--99"
}
val basePath = Environment.getExternalStorageDirectory().toString() + File.separator + AppConstant.PHOTO_MNEMO
images = util.getImages(basePath + File.separator + folderName)
images.indices
.filter { images[it].name.contains(query) }
.forEach { c.addRow(arrayOf(it, images[it].name, images[it].path)) }
adapter.changeCursor(c)
return
}
private fun setItemsVisibility(menu: Menu?, exception: MenuItem?, visible: Boolean) {
if (menu == null) return
(0..menu.size() - 1)
.map { menu.getItem(it) }
.filter { it !== exception }
.forEach { it?.isVisible = visible }
}
}