android searchview setOnActionExpandListener на Honeycomb 3.2

Я разрабатываю приложение для Android 3.2 и выше с помощью android-support-v4. Мне нужно реализовать OnActionExpandListener для «перехвата», когда SearchView на панели действий расширяется, а когда сворачивается. Мой код для Android 4.0 и выше нормально, а для 3.2 нет.

меню.xml

<item android:id="@+id/menu_search"
    android:title="@string/menu_search"
    android:icon="@android:drawable/ic_menu_search"
    android:showAsAction="collapseActionView|always"
    android:actionViewClass="android.widget.SearchView" />

MyActivity.java

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.reader, menu);

    final MenuItem searchMI = menu.findItem(R.id.menu_search);
    if(searchView == null) {
        //searchView = (SearchView) searchMI.getActionView();
        searchView = (SearchView) MenuItemCompat.getActionView(searchMI);
        searchView.setOnQueryTextListener(this);
        searchView.setOnSuggestionListener(this);
        searchView.setOnCloseListener(new OnCloseListener() {

            @Override
            public boolean onClose() {
                //some code
                return false;
            }
        });
    }


    int currentapiVersion = android.os.Build.VERSION.SDK_INT;
    if (currentapiVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR2) {
        MenuItemCompat.setShowAsAction(searchMI, MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
        MenuItemCompat.setOnActionExpandListener(searchMI, new OnActionExpandListener() {

            /* (non-Javadoc)
             * @see android.support.v4.view.MenuItemCompat.OnActionExpandListener#onMenuItemActionExpand(android.view.MenuItem)
             */
            @Override
            public boolean onMenuItemActionExpand(MenuItem item) {
                Toast.makeText(getApplicationContext(), "onMenuItemActionExpand", Toast.LENGTH_SHORT).show();
                return true;
            }

            /* (non-Javadoc)
             * @see android.support.v4.view.MenuItemCompat.OnActionExpandListener#onMenuItemActionCollapse(android.view.MenuItem)
             */
            @Override
            public boolean onMenuItemActionCollapse(MenuItem item) {
                Toast.makeText(getApplicationContext(), "onMenuItemActionExpand", Toast.LENGTH_SHORT).show();
                return true;
            }
        });
    } else {
        searchMI.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {

            @Override
            public boolean onMenuItemActionExpand(MenuItem item) {
                Toast.makeText(getApplicationContext(), "MenuItem#onMenuItemActionExpand", Toast.LENGTH_SHORT).show();
                return true;
            }

            @Override
            public boolean onMenuItemActionCollapse(MenuItem item) {
                Toast.makeText(getApplicationContext(), "MenuItem#onMenuItemActionExpand", Toast.LENGTH_SHORT).show();
                return true;
            }
        });
    }
}

Почему для Honeycomb методы прослушивателя не вызываются?

Большое спасибо.


person critical    schedule 12.11.2013    source источник
comment
Просто мимолетное примечание, так как хорошие ответы размещены ниже. Есть две проблемы: (1) должно быть app:showAsAction, а не android:showAsaction, а также app:actionViewClass. (2) Сам код должен безоговорочно использовать MenuItemCompat.setOnActionExpandListener независимо от платформы. По иронии судьбы у всех, кто сюда приезжает, есть проблема №1; но в коде ОП нет проблемы №1; у него проблема №2. Просто говорю'.   -  person Robin Davies    schedule 16.11.2015


Ответы (5)


Вы, вероятно, пропустили тот факт (как и я), что интерфейс `MenuItemCompat.OnActionExpandListener' имеет статическую реализацию, а не метод экземпляра.

Итак, если у вас есть класс, который реализует MenuItemCompat.OnActionExpandListener, то в этом классе вам нужно установить его в качестве слушателя следующим образом:

    MenuItem menuItem =  menu.findItem(R.id.search);
    if (menuItem != null) {
        MenuItemCompat.setOnActionExpandListener(menuItem,this);
        MenuItemCompat.setActionView(menuItem, mSearchView);
    }

Та же парадигма применяется к setActionView... вместо того, чтобы вызывать menuItem.setActionView(this), вы передаете menuItem в качестве первого аргумента статической версии MenuItemCompat.setActionView и следуете с другими аргументами.

person Dan Danz    schedule 25.12.2013
comment
Привет, Дэн. Ваше решение работает для меня. Большое спасибо. Вы спасли мой день. - person Ashokchakravarthi Nagarajan; 03.12.2014
comment
Ваше решение работает, большое спасибо. Еще одна вещь, ответ выше вам также необходим для правильной работы. - person ShahrozKhan91; 28.01.2015

Чтобы MenuItemCompat.setOnActionExpandListener работал, вы должны добавить "collapseActionView" в пункт меню, например -

<item android:id="@+id/action_search"
          android:icon="@drawable/ic_action_search"
          android:title="@string/action_search"
          app:showAsAction="ifRoom|collapseActionView"
          app:actionViewClass="android.support.v7.widget.SearchView" />

А в onCreateOptionsMenu можно использовать так -

MenuItemCompat.setOnActionExpandListener(menu_search,
            new OnActionExpandListener()
            {
                @Override
                public boolean onMenuItemActionCollapse(MenuItem item)
                {
                    // Do something when collapsed
                    return true; // Return true to collapse action view
                }

                @Override
                public boolean onMenuItemActionExpand(MenuItem item)
                {
                    // Do something when expanded
                    return true; // Return true to expand action view
                }
            });
person Fenil    schedule 28.08.2014

Я обнаружил, что MenuItemCompat.setOnActionExpandListener(...) не работает, если вы не пройдете:

    searchItem
            .setShowAsAction(MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
                    | MenuItemCompat.SHOW_AS_ACTION_ALWAYS);

Но это меняет SearchView и заменяет DrawerToggle стрелкой назад.

Я хотел сохранить исходные представления и по-прежнему отслеживать развернутое/свернутое состояние и использовать поддерживаемое представление поиска.

Решение:

Когда android.support.v7.widget.SearchView изменяет состояние представления LinearLayout с идентификатором android.support.v7.appcompat.R.id.search_edit_frame, значение видимости изменяется с View.VISIBLE на View.GONE и наоборот. Поэтому я добавляю ViewTreeObserver для отслеживания изменения видимости рамки редактирования поиска.

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="@android:drawable/ic_menu_search"
    android:title="@string/search"
    app:actionViewClass="android.support.v7.widget.SearchView"
    app:showAsAction="always"/>

</menu>

В деятельности:

import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.SearchView;
import android.view.Menu;
import android.view.MenuItem;

..........

private View mSearchEditFrame;

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_search, menu);
    MenuItem searchItem = (MenuItem) menu.findItem(R.id.action_search);

    SearchView searchView = (SearchView) MenuItemCompat
            .getActionView(searchItem);
    searchView.setSubmitButtonEnabled(false);
    mSearchEditFrame = searchView
            .findViewById(android.support.v7.appcompat.R.id.search_edit_frame);

    ViewTreeObserver vto = mSearchEditFrame.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        int oldVisibility = -1;

        @Override
        public void onGlobalLayout() {

            int currentVisibility = mSearchEditFrame.getVisibility();

            if (currentVisibility != oldVisibility) {
                if (currentVisibility == View.VISIBLE) {
                    Log.v(TAG, "EXPANDED");
                } else {
                    Log.v(TAG, "COLLAPSED");
                }

                oldVisibility = currentVisibility;
            }

        }
    });

    return super.onCreateOptionsMenu(menu);
}

Спасибо!

person Sir NIkolay Cesar The First    schedule 27.02.2015

Ваш прослушиватель должен быть MenuItemCompat.OnActionExpandListener() .

MenuItemCompat.setOnActionExpandListener(searchItem,
            new MenuItemCompat.OnActionExpandListener() {

}
person yajnesh    schedule 04.12.2013
comment
В моем коде: MenuItemCompat.setOnActionExpandListener(searchMI, new OnActionExpandListener() {...}) OnActionExpandListener находится в классе MenuItemCompat. Ваше предложение не работает. - person critical; 05.12.2013
comment
проверь мой ответ - person Sir NIkolay Cesar The First; 27.02.2015

спасибо за вашу помощь, ваше решение работает для меня. и я хотел бы проголосовать за вас, но я только что понял, что у меня только 1 репутация,(;′⌒`)

на самом деле, мое решение похоже на ваше, только в XML-файле меню есть одно отличие:

    <item
    android:id="@+id/apps_menu_search"
    android:icon="@drawable/ic_action_search"
    android:title="@string/apps_menu_search"
    android:visible="true"
    app:actionViewClass="android.support.v7.widget.SearchView"
    app:showAsAction="ifRoom|collapseActionView" />
person Lei Leon    schedule 31.07.2015