androidsearchviewmaterial-components-android

Android SearchView OnQueryTextListener Not Working


I'm trying to implement a searchView in a Fragment, using Material UI components but I can't seem to get any output when setting the listener, so I'm guessing I have missed a step in the setup process.

The problem

So when I load my app and start typing in the search view, I expect to see some output in the logcat of Android Studio, but nothing seems to be shown.

What I've done

Created an XML layout with Material UI toolbar.

...
    <com.google.android.material.appbar.AppBarLayout
    android:id="@+id/app_bar_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fitsSystemWindows="true"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <com.google.android.material.appbar.MaterialToolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="#000000"
        app:menu="@menu/menu_search"
        app:navigationIcon="@drawable/ic_arrow_back" />

</com.google.android.material.appbar.AppBarLayout>
...

Created a menu item (menu_search.xml)

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
    android:id="@+id/action_search"
    android:icon="@drawable/ic_search_24dp"
    android:title="Menu Search"
    app:actionViewClass="androidx.appcompat.widget.SearchView"
    app:showAsAction="always" />

In my Fragment

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    inflater.inflate(R.menu.menu_search, menu)

    val search = menu.findItem(R.id.action_search)
    val searchView = search.actionView as SearchView

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

        override fun onQueryTextChange(newText: String?): Boolean {
            Timber.d("onQueryTextChange $newText")
            return false
        }
    })

    super.onCreateOptionsMenu(menu, inflater)
}

Other things that might be relevant

Any help would be greatly appreciated, thanks.


Solution

  • Try to instantiate your menu in the onCreateView method of the fragment:

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? 
    {
        val view = inflater.inflate(<your-fragment-layout>, container, false)
    
        view.findViewById<MaterialToolbar>(R.id.toolbar).apply {
            val searchView = menu.findItem(R.id.action_search).actionView
            searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
                override fun onQueryTextSubmit(query: String?): Boolean {
                    Timber.d("onQueryTextSubmit")
                    return false
                }
    
                override fun onQueryTextChange(newText: String?): Boolean {
                    Timber.d("onQueryTextChange $newText")
                    return false
                }
            })
        }
        
        ...
    
        return view
    }