ActionMode - SearchView 不工作actionView 为空

问题描述

我最近致力于在用户点击 SearchView 中的搜索时激活 ActionMode 中的 onoptionsItemSelected

但是,调试后我无法访问 SearchView,它的 actionView 显然为空。有人能帮我解决这个问题吗?

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>

对于我使用的所有 androidx.appcompat.widget.SearchView,我都使用了 SearchView。但我仍然不知道为什么我无法访问 SearchView 中的 ActionMode。请给我一些帮助。

解决方法

我以前遇到过同样的问题,对我有用的是以编程方式设置 ActionView,而不是在菜单 xml 中。

这样做:

首先:从菜单中删除操作 ViewClass

<?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"/>
...

第二:创建一个 SearchView

的实例

第三: 扩充您要设置其 actionViewClass 的菜单项,并使用 setActionView(view) 设置实例化的 SearchView

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

    moreMenuBtn.isVisible = false
    layout_chatbox.hide()
    
    // Step 2:
    val searchView = SearchView(this)
    searchView.setQuery(null,true)
    searchView.queryHint = "Search"

    // Step 3:
    val searchItem = menu?.findItem(R.id.search_item_btn)
    searchItem.setActionView(searchView)

    return true
}
,

我有一个解决方法。 就我而言,我将在 actionMode 的标题中添加一个 customview。 这是我的解决方案。

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(只是一个简单的 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(删除搜索视图项目)

<?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>

最终的输出是这样的

enter image description here