ActionMode - SearchView не работает (actionView имеет значение null)

Недавно я работал над активацией 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. Пожалуйста, помогите мне.


person Teo    schedule 31.12.2020    source источник


Ответы (2)


Раньше я сталкивался с той же проблемой, и у меня сработало программное обеспечение 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, и используйте _ 5_, чтобы установить ваш экземпляр 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
}
person Zain    schedule 31.12.2020
comment
Привет, это действительно хорошее решение для включения основных функций SearchView. Но в моем случае я хочу, чтобы другой menuItem сохранялся при включении SearchView. Я прикрепил свое решение ниже, и вы можете посмотреть и прокомментировать, если я сделаю что-то не так - person Teo; 02.01.2021

У меня был обходной путь. В моем случае я добавлю customview к заголовку actionMode. Вот мое решение.

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>

Окончательный результат будет таким

введите описание изображения здесь

person Teo    schedule 02.01.2021
comment
Хорошая работа .. но почему бы не добавить androidx.appcompat.widget.SearchView вместо EditText в макет .. это облегчит функции поиска больше, чем EditText - person Zain; 02.01.2021
comment
Спасибо за предложение! Когда я применял исправление, я не думал о SearchView. Теперь он работает как шарм с SearchView в customView :) - person Teo; 04.01.2021
comment
@Zain Кстати, не могли бы вы помочь мне проголосовать за мой вопрос? так как мне нужно заработать больше репутации в StackOverFlow :). Цените вашу помощь. - person Teo; 04.01.2021