Search code examples
androidkotlinandroid-menuandroid-actionmode

ActionMode - SearchView not working (actionView is null)


I recently working on activating SearchView in ActionMode when user click on Search in onOptionsItemSelected.

However, I cant get access to the SearchView as after debugging, its actionView apparently to be null. Can anyone help me with this?

override fun onOptionsItemSelected(item: MenuItem): Boolean {
     R.id.chat_search -> {
          if (searchActionMode == null) {
             searchActionMode = startActionMode(searchActionModeCallBack)
          }
}

ActionModeCallBack

private val searchActionModeCallBack = object: ActionMode.Callback {
        private lateinit var mSearchView: SearchView

        override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean {
            menuInflater.inflate(R.menu.menu_search_message, menu)

            moreMenuBtn.isVisible = false
            layout_chatbox.hide()

            return true
        }

        override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean {
            val searchItem = menu?.findItem(R.id.search_item_btn)
            if(searchItem?.actionView != null) {      <---- this seachview.actionView keeps return null
                mSearchView = searchItem.actionView as SearchView
                mSearchView.isIconified = false

                mSearchView.onQueryTextChanged { newText ->

                }
            }

            return true
        }

        override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
            when(item?.itemId) {
                R.id.search_item_up -> {
                    "UP".showToast(this@ChatActivity)
                }
                R.id.search_item_down -> {
                    "DOWN".showToast(this@ChatActivity)
                }
                R.id.search_item_btn -> {
                    "SEARCH".showToast(this@ChatActivity)    <-- when click on "Search" Button, "Search" is toasted.
                }
            }
            return false
        }

        override fun onDestroyActionMode(mode: ActionMode?) {
            searchActionMode = null
            moreMenuBtn.isVisible = true
            layout_chatbox.show()
        }

    }

menu_search_message.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <group android:id="@+id/group_search_mode">

        <item
            android:id="@+id/search_item_btn"
            android:icon="@drawable/ic_baseline_search_24"
            app:showAsAction="always"
            android:title="@string/search"
            app:actionViewClass="androidx.appcompat.widget.SearchView" />

        <item
            android:id="@+id/search_item_up"
            android:icon="@drawable/ic_baseline_arrow_drop_up_24"
            app:showAsAction="always"
            android:title="@string/up"/>

        <item
            android:id="@+id/search_item_down"
            android:icon="@drawable/ic_baseline_arrow_drop_down_24"
            app:showAsAction="always"
            android:title="@string/down"/>

    </group>

</menu>

I used androidx.appcompat.widget.SearchView for all of the SearchView I used. But still I had no idea why I can't access to the SearchView in ActionMode. Please give me some help.


Solution

  • I had a workaround for this. In my case, I will add a customview to the actionMode's title. Here is my solution.

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
         R.id.chat_search -> {
              if (searchActionMode == null) {
                 searchActionMode = startActionMode(searchActionModeCallBack)
                 val view = layoutInflater.inflate(R.layout.custom_searchview, null)
                 searchActionMode?.customView = view   <-- ADD YOUR CUSTOM VIEW
    
                 val etSearch = view.findViewById<EditText>(R.id.et_search)
                 etSearch.requestFocus()
                 etSearch.doOnTextChanged { text, start, before, count ->
                      // TODO - handle the search query here
                 }
       }
    }
    

    custom_searchview.xml (Just a simple EditText)

    <RelativeLayout
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <EditText
            android:id="@+id/et_search"
            android:layout_alignParentStart="true"
            android:maxLines="1"
            android:ellipsize="end"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@null"
            android:padding="10dp"
            android:layout_marginEnd="50dp"
            android:hint="Search..."
            android:textColorHint="@color/colorWhite"
            android:textColor="@color/colorWhite"/>
    
    
    </RelativeLayout>
    

    menu_search_message.xml (REMOVE THE SEARCH VIEW ITEM)

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
    <!--    <item-->         <-- remove the searchView from xml
    <!--        android:id="@+id/search_item_btn"-->
    <!--        android:icon="@drawable/ic_baseline_search_24"-->
    <!--        android:title="@string/search"-->
    <!--        android:enabled="true"-->
    <!--        android:actionLayout="@layout/custom_searchview"-->
    <!--        app:showAsAction="collapseActionView|always" />-->
    
        <item
            android:id="@+id/search_item_up"
            android:icon="@drawable/ic_baseline_arrow_drop_up_24"
            android:orderInCategory="2"
            android:title="@string/up"
            app:showAsAction="always" />
    
        <item
            android:id="@+id/search_item_down"
            android:icon="@drawable/ic_baseline_arrow_drop_down_24"
            android:orderInCategory="3"
            android:title="@string/down"
            app:showAsAction="always" />
    
    
    </menu>
    

    Final output will be like this

    enter image description here