OnCloseListener в SearchView не работает - PullRequest
93 голосов
/ 17 февраля 2012

Я пытаюсь добавить поддержку SearchView в панели действий Android 3.0+, но не могу заставить OnCloseListener работать.

Вот мой код:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu, menu);
    searchView = (SearchView) menu.findItem(R.id.search_textbox).getActionView();
    searchView.setOnQueryTextListener(new OnQueryTextListener() {
        @Override
        public boolean onQueryTextChange(String newText) {
            searchLibrary(newText);
            return false;
        }
        @Override
        public boolean onQueryTextSubmit(String query) { return false; }
    });
    searchView.setOnCloseListener(new OnCloseListener() {
        @Override
        public boolean onClose() {
            System.out.println("Testing. 1, 2, 3...");
            return false;
        }
    });
    return true;
}

Поиск отлично работает, и все работают, кроме OnCloseListener.Ничего не печатается в Logcat.Вот Logcat, когда я нажимаю кнопку «Закрыть»:

02-17 13:01:52.914: I/TextType(446): TextType = 0x0
02-17 13:01:57.344: I/TextType(446): TextType = 0x0
02-17 13:02:02.944: I/TextType(446): TextType = 0x0

Я просмотрел документацию и образцы, но, похоже, ничего не изменило.Я использую его на Asus Transformer Prime и Galaxy Nexus, оба на Ice Cream Sandwich.Есть идеи?

Обновление:

Да - System.out.println() работает работает.Вот доказательство:

   @Override
 public boolean onQueryTextChange(String newText) {
    System.out.println(newText + "hello");
    searchLibrary(newText);
    return false;
 }

Результаты в этом Logcat:

02-17 13:04:20.094: I/System.out(21152): hello
02-17 13:04:24.914: I/System.out(21152): thello
02-17 13:04:25.394: I/System.out(21152): tehello
02-17 13:04:25.784: I/System.out(21152): teshello
02-17 13:04:26.064: I/System.out(21152): testhello

Ответы [ 17 ]

138 голосов
/ 22 мая 2012

Я тоже сталкиваюсь с этой проблемой, и у меня нет выбора, кроме как отказаться от "oncloselistener". Вместо этого вы можете получить свой menuItem, затем setOnActionExpandListener. Затем переопределите unimplents методы.

@Override
public boolean onMenuItemActionExpand(MenuItem item) {
    // TODO Auto-generated method stub
    Log.d("*******","onMenuItemActionExpand");
    return true;
}

@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
    //do what you want to when close the sesarchview
    //remember to return true;
    Log.d("*******","onMenuItemActionCollapse");
    return true;
}
60 голосов
/ 12 августа 2013

Для Android API 14+ (ICS и выше) используйте этот код:

// When using the support library, the setOnActionExpandListener() method is
// static and accepts the MenuItem object as an argument
MenuItemCompat.setOnActionExpandListener(menuItem, 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
    }
});

Для получения дополнительной информации: http://developer.android.com/guide/topics/ui/actionbar.html#ActionView

Ссылка: onActionCollapse / onActionExpand

27 голосов
/ 19 октября 2012

Для этой проблемы я придумал что-то вроде этого,

private SearchView mSearchView;

@TargetApi(14)
@Override
public boolean onCreateOptionsMenu(Menu menu)
{

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.conversation_index_activity_menu, menu);

    mSearchView = (SearchView) menu.findItem(R.id.itemSearch).getActionView();

    MenuItem menuItem = menu.findItem(R.id.itemSearch);

    int currentapiVersion = android.os.Build.VERSION.SDK_INT;
    if (currentapiVersion >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    {
        menuItem.setOnActionExpandListener(new OnActionExpandListener()
        {

            @Override
            public boolean onMenuItemActionCollapse(MenuItem item)
            {
                // Do something when collapsed
                Log.i(TAG, "onMenuItemActionCollapse " + item.getItemId());
                return true; // Return true to collapse action view
            }

            @Override
            public boolean onMenuItemActionExpand(MenuItem item)
            {
                // TODO Auto-generated method stub
                Log.i(TAG, "onMenuItemActionExpand " + item.getItemId());
                return true;
            }
        });
    } else
    {
        // do something for phones running an SDK before froyo
        mSearchView.setOnCloseListener(new OnCloseListener()
        {

            @Override
            public boolean onClose()
            {
                Log.i(TAG, "mSearchView on close ");
                // TODO Auto-generated method stub
                return false;
            }
        });
    }


    return super.onCreateOptionsMenu(menu);

}
18 голосов
/ 04 июля 2014

Я столкнулся с той же проблемой на Android 4.1.1.Похоже, это известная ошибка: https://code.google.com/p/android/issues/detail?id=25758

В любом случае, в качестве обходного пути я использовал слушатель изменения состояния (когда SearchView отсоединен от панели действий, он также, очевидно, закрыт).

view.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {

    @Override
    public void onViewDetachedFromWindow(View arg0) {
        // search was detached/closed
    }

    @Override
    public void onViewAttachedToWindow(View arg0) {
        // search was opened
    }
});

Вышеупомянутый код работал хорошо в моем случае.


Я отправляю тот же ответ здесь: https://stackoverflow.com/a/24573266/2162924

9 голосов
/ 18 февраля 2012

Я использовал хак, который хорошо работает для моих целей - не уверен, что он будет работать во всех целях. Во всяком случае, я делаю проверку, чтобы увидеть, если поисковый запрос пуст. Это на самом деле не связано с SearchView OnCloseListener - это все равно не работает!

searchView.setOnQueryTextListener(new OnQueryTextListener() {
            @Override
            public boolean onQueryTextChange(String newText) {
                if (newText.length() > 0) {
                    // Search
                } else {
                    // Do something when there's no input
                }
                return false;
            }
            @Override
            public boolean onQueryTextSubmit(String query) { return false; }
        });
6 голосов
/ 30 мая 2015

Ну, это решило мою проблему:

Пункт меню с showAsAction="always"

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

и в активности

searchView.setOnCloseListener(new OnCloseListener() {

        @Override
        public boolean onClose() {

            Log.i("SearchView:", "onClose");
            searchView.onActionViewCollapsed();
            return false;
        }
    });
2 голосов
/ 24 ноября 2014

Чтобы заставить OnCloseListener работать, убедитесь, что для showAsAction установлено значение always в пункте меню поиска.

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:tools="http://schemas.android.com/tools"
      tools:context=".SearchActivity">

    <item
        android:id="@+id/search"
        android:title="@string/search"
        android:icon="@drawable/ic_search_toolbar"
        app:showAsAction="always"
        app:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>
2 голосов
/ 14 августа 2014

Я столкнулся с той же проблемой, когда onCloseListener не вызывает SearchView.Поймите из ошибки, поднятой в 25758 , и некоторые сообщения, которые я прочитал, чтобы вызвать onCloseListener, вам нужно установить:

searchView.setIconifiedByDefault(true);

Но для моего случая я хотел, чтобы поисквид открыт и не отображается все время.Мне удается решить эту проблему, добавив еще одну строку ниже:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.search_bar, menu);
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    searchView = (SearchView) menu.findItem(R.id.search).getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setOnQueryTextListener(queryTextListener);
    searchView.setIconifiedByDefault(true);
    searchView.setIconified(false);
    return true;
}

searchView.setIconified (false) заставит searchView открыться, несмотря на то, что в предыдущей строке по умолчанию в значке было указано значение true.Таким образом, мне удалось получить SearchView, который все время открывается, и заставить его вызывать onCloseListener.

1 голос
/ 14 октября 2017

Создайте пункт меню с app:showAsAction, установленным на всегда.

<item   
 android:id="@+id/action_search"  
 android:title="..."  
 android:icon="..."  
 app:actionViewClass="android.support.v7.widget.SearchView"  
 app:showAsAction="always"/>

При создании SearchView в методе onCreateOptionsMenu сделайте что-то похожее

inflater.inflate(R.menu.menu_search, menu);
final MenuItem item = menu.findItem(R.id.action_search);
final SearchView search = (SearchView) item.getActionView();
search.setQueryHint(getString(R.string.search_brand_item));
search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
  @Override
  public boolean onQueryTextSubmit(String query) {
    // add your code
    return false;
  }

  @Override
  public boolean onQueryTextChange(String newText) {
    // add your code 
    return false;
  }
});
search.setOnCloseListener(new SearchView.OnCloseListener() {
  @Override
  public boolean onClose() {
    // add your code here
    return false;
  }
});
search.setIconifiedByDefault(true); // make sure to set this to true

search.setIconifiedByDefault(true) должен быть установлен в true для вызова onClose() метод SearchView.OnCloseListener(), созданный выше.

1 голос
/ 27 февраля 2015

Для проблемы MenuItemCompat Я добавил ViewTreeObserver для отслеживания состояния видимости. Вы можете проверить мой ответ здесь: https://stackoverflow.com/a/28762632/1633609

...