Панель действий показывает только один элемент рядом с видом поиска

#android #android-actionbar #searchview

#Android #android-панель действий #searchview

Вопрос:

Я хочу иметь вид поиска и две кнопки на панели действий. Итак, я создал menu/options_menu.xml:

 <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@ id/action_search"
    android:title="Search"
    android:icon="@drawable/ic_menu_search"
    android:showAsAction="always"
    android:actionViewClass="android.widget.SearchView" />

<item
    android:title="Route"
    android:id="@ id/action_route"
    android:icon="@drawable/route"
    android:showAsAction="always" />

<item
    android:title="Cancel"
    android:id="@ id/action_cancel"
    android:icon="@drawable/cancel"
    android:showAsAction="always" />

</menu>
  

Я раздуваю его в коде:

 @Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconifiedByDefault(false);

    return true;
}
  

Это то, что я получаю:

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

Как вы можете видеть, отображается только первый элемент («маршрут»). Я могу сделать видимым второй элемент («отмена»), если я разрешу значок виджета поиска:

     //searchView.setIconifiedByDefault(false);
  

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

Тем не менее, я хочу, чтобы виджет поиска был расширен и оба элемента были видны. Возможно ли это?

Обновить

Мне удалось сделать их видимыми, установив android:orderInCategory="1" для «Маршрут» и «Отмена» и android:orderInCategory="2" для виджета поиска:

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

Это почти то, что я хотел. Проблема в том, что я хочу, чтобы виджет поиска был первым (крайним слева), а затем эти два элемента. Возможно ли это?

Обновление 2

Я попробовал «рекомендуемый» способ. Я установил для SearchView :

 android:showAsAction="always|collapseActionView"
  

После того, как я нажимаю на значок поиска, я получаю расширенный вид:

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

Две проблемы:

  1. (Незначительный) Пользовательский интерфейс навигации занимает комнату слева, что уменьшает доступное пространство для SearchView .
  2. (Основной) Значок Android отображается как часть пользовательского интерфейса навигации. Могу ли я избавиться от него?

Комментарии:

1. Поймите это. Пользователь нажмет кнопку поиска и захочет взаимодействовать с расширенным виджетом поиска. Остальное их не волнует. Они хотят выполнить поиск. Любая другая кнопка просто отвлекает. Любые кнопки, которые не связаны с текущей задачей, могут быть скрыты. Это псевдопроблема. Сверните кнопку поиска по умолчанию, как показано здесь developer.android.com/training/search/setup.html .

2. @Eugen Pechanec Спасибо за ваш комментарий. Я попробовал то, что вы предлагаете, и обновил свой вопрос. Могу ли я удалить значок Android, который отображается в левой части панели действий?

3. Если вы используете тему Material или AppCompat (настоятельно рекомендуется), стрелка навигации закрывает вид поиска, а значок исчезает. Если вы не можете использовать темы Material или AppCompat, позвоните getActionBar().setIcon(new ColorDrawable(0)); , чтобы удалить значок.

4. @Nick мой ответ работает или нет?

5. @Nick мой ответ полезен?

Ответ №1:

Создал одну демонстрацию, проверьте ее :

menu.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:title="Search"
        android:icon="@android:drawable/ic_search_category_default"
        app:actionLayout="@layout/searchview"
        app:showAsAction="always|collapseActionView"/>

    <item
        android:title="Route"
        android:id="@ id/action_route"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="always" />

    <item
        android:title="Cancel"
        android:id="@ id/action_cancel"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="always" />

</menu>
  

searchview.xml :

 <?xml version="1.0" encoding="utf-8"?>
<SearchView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
  

Java :

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

        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
        if(searchItem!=null) {
            searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
            searchView.setIconifiedByDefault(false);
        }

        return true;
    }
  

Отредактированная Java на основе требований (всегда открывайте searchview) :

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

        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        MenuItem searchItem = menu.findItem(R.id.action_search);
        searchItem.expandActionView();
        final SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
        if(searchItem!=null) {
            searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
            searchView.setIconifiedByDefault(false);
            // This listener use for handle back press if you want to go back without collapsing searchview
            MenuItemCompat.setOnActionExpandListener(searchItem,new MenuItemCompat.OnActionExpandListener() {

                @Override
                public boolean onMenuItemActionExpand(MenuItem item) {
                    return true;
                }

                @Override
                public boolean onMenuItemActionCollapse(MenuItem item) {
                    onBackPressed();
                    return false;
                }
            });
        }
        return true;
    }
  

Скриншоты :

Без щелчка С помощью щелчка

Комментарии:

1. MenuItemCompat.setOnActionExpandListener не рекомендуется. Есть ли какой-либо код для его замены?

Ответ №2:

Я сделал это, установив максимальную ширину для вида поиска, равную ширине экрана, минус ширина элемента действия.

res/menu/search.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
        android:id="@ id/action_search"
        android:icon="@drawable/ic_search_white_24dp"
        android:title="@string/title_search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="always" />
    <item
        android:id="@ id/action_filter"
        android:icon="@drawable/ic_filter_list_white_24dp"
        android:title="@string/title_filter"
        app:showAsAction="always" />
</menu>
  

Действие или фрагмент:

 @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.search, menu);
    searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
    searchView.setIconified(false);
    searchView.setMaxWidth(getSearchViewMaxWidth());
    searchView.setOnCloseListener(new SearchView.OnCloseListener() {
        @Override
        public boolean onClose() {
            performSearch("");
            return true; // Disable dismissing the search view
        }
    });
    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            performSearch(query);
            return true;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            return false;
        }
    });
}

@Px
private int getSearchViewMaxWidth() {
    final int screenWidth = getResources().getDisplayMetrics().widthPixels;
    final int actionItemWidth = getResources().getDimensionPixelSize(R.dimen.action_item_width);
    return screenWidth - actionItemWidth;
}
  

res/values/dimens.xml

 <?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- ... -->
    <dimen name="action_item_width">48dp</dimen>

</resources>
  

Ответ №3:

Измените свой onCreateOptionsMenu следующим образом, чтобы явно установить пункты меню, видимые, когда элемент SearchView меню имеет фокус.

 @Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconifiedByDefault(false);


    if (menu.getItem(0).isFocused()) //detect if search view has focus 
    {
        //explicitly set menu items visible
        menu.getItem(1).setVisible(true);
        menu.getItem(2).setVisible(true);
    }

    return true;    
}
  

Комментарии:

1. у меня это не работает. второй элемент (отмена) по-прежнему не отображается в портретном режиме.

Ответ №4:

вы можете настроить ширину расширенного представления поиска следующим образом

 @Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconifiedByDefault(false);

    ActionBar.LayoutParams params = new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.MATCH_PARENT);
        params.width=500;
        searchView.setLayoutParams(params);
        menu.findItem(R.id.action_search).expandActionView();
    return true;
}
  

Ответ №5:

попробуйте это:

 <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@ id/action_search"
    android:title="Search"
    android:icon="@drawable/ic_menu_search"
    android:orderInCategory="1"
    android:showAsAction="collapseActionView|ifRoom"
    android:actionViewClass="android.widget.SearchView" />

<item
    android:title="Route"
    android:id="@ id/action_route"
    android:icon="@drawable/route"
    android:orderInCategory="2"
    android:showAsAction="always" />

<item
    android:title="Cancel"
    android:id="@ id/action_cancel"
    android:icon="@drawable/cancel"
    android:orderInCategory="2"
    android:showAsAction="always" />

</menu>