Actionbar - 隐藏除搜索栏以外的所有菜单项

6

我是一名有用的助手,可以为您进行文本翻译。

我在我的操作栏中有一个菜单,其中有两个项目。在打开搜索视图“a piece of pen”之后,它仍然显示。如何隐藏它?

menu.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/search"
        android:title="@string/search"
        android:icon="@drawable/ic_search"
        app:actionViewClass="android.widget.SearchView"
        app:showAsAction="ifRoom|withText" />

    <item
        android:id="@+id/edit"
        android:icon="@drawable/ic_edit"
        android:title="@string/edit"
        app:showAsAction="ifRoom|withText" />

</menu>

操作栏(Actionbar): search closed

展开搜索视图的操作栏(Actionbar with search view opened): search open

我也尝试过:

app:showAsAction="collapseActionView|ifRoom"

但在这种情况下,我有:

collapseActionView

我想得到与第二张图片相同的结果。但是编辑图标应该被隐藏或者最好作为一个整体显示。

编辑

根据Ahmad Alsanie的回答,我写了类似于这样的代码:

SearchView view = (SearchView) menu.findItem(R.id.search).getActionView();
view.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
    if (hasFocus) 
        menu.findItem(R.id.edit).setVisible(false);
});

这个功能已经实现了,但是我想知道怎样在关闭搜索视图后重新显示编辑图标。我尝试使用setOnCloseListener,但是没有成功。


请查看此链接:http://www.edumobile.org/android/action-bar-search-view/ - Pier Giorgio Misley
谢谢,我试过了,但是和第三张图片一样(只有编程代码,没有XML)。 - Bakus123
好的,什么也没有发生 :) - Bakus123
这完美地解决了这个问题。 - Anmol
5个回答

8

我尝试了以上所有解决方案,但都没有对我起作用。最接近的是@ysfcyln的解决方案,但还不完美。

所以我将提供我的解决方案版本,并逐步解释。

第一步:

我遇到的关键问题:

  • searchView没有覆盖整个操作栏
  • actionUp按钮未显示

一旦我声明app:showAsAction=collapseActionView,它就完成了所有魔法,即覆盖整个操作栏并提供返回按钮。

注意:其他actionMenuItem仍然可见。(问题2)

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_add"
        android:icon="@drawable/ic_baseline_note_add_24px"
        android:title="@string/add_note"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/action_setting"
        android:icon="@drawable/ic_icons_settings"
        android:title="@string/action_settings"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/action_search"
        android:icon="@drawable/ic_search_24px"
        android:title="@string/search_hint"
        app:actionViewClass="androidx.appcompat.widget.SearchView"
        app:showAsAction="always|collapseActionView" />

</menu>

步骤 2:

为了解决问题 2(隐藏其他菜单项),我使用了 MenuItem.setOnActionExpandListener

以下代码来自我的项目,仅供参考,根据您的项目进行更改。

Activity/Fragment(下面的代码来自片段):

 override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    super.onCreateOptionsMenu(menu, inflater)
...
...
   //get all menuItem using the id in onCreateOptionsMenu()
   val searchActionMenuItem = menu.findItem(R.id.action_search)
   val settingActionMenuItem = menu.findItem(R.id.action_setting)
   val addActionMenuItem = menu.findItem(R.id.action_add)

   if (searchActionMenuItem is MenuItem) {
       searchActionMenuItem.setOnActionExpandListener(object :
       MenuItem.OnActionExpandListener {
       override fun onMenuItemActionExpand(p0: MenuItem?): Boolean {
          settingActionMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
          addActionMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
          return true
       }

      override fun onMenuItemActionCollapse(p0: MenuItem?): Boolean {
          activity?.invalidateOptionsMenu()
          return true
       }
      })
   }
...
...
}

需要注意的要点包括:

  • Use setOnActionExpandListener to check the change of SearchView state not the searchView's Listener as declared below.

    searchView.setOnSearchClickListener {  }  // Work's as expected
    searchView.setOnCloseListener {  }        // Doesn't get triggered as expected 
    
  • Set the ShowAsAction of other MenuItem's to MenuItem.SHOW_AS_ACTION_NEVER inside onMenuItemActionExpand() as it will force other item's to OverFlow Menu once SearchView is expanded.(Changing Visibility of MenuItem will not do the job)

     settingActionMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)  
     addActionMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
    
  • onMenuItemActionCollapse() call's activity's invalidateOptionsMenu().The reason is to reset the Action Menu bar Back to it's original state.

以上就是我的全部内容,如果我漏掉了任何情况,请在下方评论区留言。

屏幕截图:

SS1

SS2

SS3


1
感谢您提供详细的描述! - Bruno Bieri
我不得不使用setOnSearchClickListener和setOnCloseListener才能使其正常工作。setActionExpandListener从未被调用过。这可能是由于不同的目标SDK,我正在使用30,或者不同的Google库版本所致。 - Kevin

3

首先,在你的onCreateOptionsMenu方法内使用以下代码:

MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.edit, menu);
if (menu.getItem(1).isFocused()) //detect if search view has focus 
    {
        //hide only option 2 which is in this case edit pen
            menu.getItem(2).setVisible(false);
    }else{
    menu.getItem(2).setVisible(true);
    }

那么使用:

invalidateOptionsMenu();//to call onCreateOptionMenu again

谢谢,我应该在哪里调用 invalidateOptionsMenu() - Bakus123
1
在需要更新菜单以显示或隐藏编辑时,请调用invalidate。可以在类中的任何位置调用,例如onCreate。 - Ahmad Sanie
menu.getItem(1)没有isFocused方法。我尝试使用SearchView view替代它,它可以正常工作,但效果仍然相同... - Bakus123
我也尝试使用view.setOnFocusChangeListener,但它仍然不起作用 :( - Bakus123
我认为你需要将 menu.getItem(2).isFocused() 更改为 menu.getItem(2).getActionView().isFocused() - Mohamed Zakaria El-Zoghbi

2

@Ahmed Awad的回答很好,但是searchView.setOnCloseListener不起作用,所以使用MenuItemCompat.setOnActionExpandListener。

menu_items.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:title="Search"
        android:icon="@drawable/ic_action_search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="always|collapseActionView"/>

    <item
        android:id="@+id/action_sort"
        android:title="Sort"
        android:icon="@drawable/ic_action_sort_alphabetically"
        app:showAsAction="always"/>

</menu>

Activity

@Override
    public boolean onCreateOptionsMenu(final Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_items, menu);
        MenuItem menuItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(menuItem);
        searchView.setMaxWidth(Integer.MAX_VALUE);
        searchView.setOnQueryTextListener(this);

/*        // Hide other menu items when searchView clicked
        searchView.setOnSearchClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                menu.findItem(R.id.action_sort).setVisible(false);
            }
        });

        // Show other menu items when SearchView closed
        searchView.setOnCloseListener(new SearchView.OnCloseListener() {
            @Override
            public boolean onClose() {
                menu.findItem(R.id.action_sort).setVisible(true);
                return false;
            }
        });*/

        MenuItemCompat.setOnActionExpandListener(menuItem, new MenuItemCompat.OnActionExpandListener() {
            @Override
            public boolean onMenuItemActionCollapse(MenuItem item) {
                // Do something when collapsed
                menu.findItem(R.id.action_sort).setVisible(true);
                return true;  // Return true to collapse action view
            }

            @Override
            public boolean onMenuItemActionExpand(MenuItem item) {
                // Do something when expanded
                menu.findItem(R.id.action_sort).setVisible(false);
                return true;  // Return true to expand action view
            }
        });

        return super.onCreateOptionsMenu(menu);
    }

由于我在这个问题上遇到了很多问题,所以我对 https://dev59.com/O4_ea4cB1Zd3GeqPQJa6#58470591 进行了改进版本。 - Anmol

0
我曾经遇到过同样的问题,在隐藏其他图标后无法正确显示它们。以下更改对我有用,你可以试试。
1- 尝试将 ShowAsAction 更改为 "always"
<item
        android:id="@+id/search"
        android:title="@string/search"
        android:icon="@drawable/ic_search"
        app:actionViewClass="android.widget.SearchView"
        app:showAsAction="always" />
<item
        android:id="@+id/edit"
        android:icon="@drawable/ic_edit"
        android:title="@string/edit"
        app:showAsAction="always" />

2- 使用 "setOnSearchClickListener" 隐藏编辑控件,如下:

SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setOnSearchClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        menu.findItem(R.id.edit).setVisible(false);
    }
});

3- 使用“setOnCloseListener”将隐藏的控件恢复为:

// Detect SearchView close
searchView.setOnCloseListener(new SearchView.OnCloseListener() {
    @Override
    public boolean onClose() {
        menu.findItem(R.id.edit).setVisible(true);
        return false;
    }
});

您不需要调用invalidate方法就可以使其工作


setOnSearchClickListener永远不会被触发。 - Hai Hack
@HaiHack 请查看此解决方案 https://dev59.com/O4_ea4cB1Zd3GeqPQJa6#58470591 - Anmol

-4
尝试在第二个菜单中使用:showAsAction="never"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接