导航抽屉滑动任何数量时隐藏ActionBar MenuItems

Syn*_*807 29 android actionbarsherlock navigation-drawer

我正在尝试实现一个导航抽屉,只要打开抽屉,它就会隐藏ActionBar中的菜单项.

我正在关注谷歌的文档,但他们的代码不会产生预期的行为.

http://developer.android.com/training/implementing-navigation/nav-drawer.html

使用此代码,当抽屉完全打开时,菜单项将被隐藏,并在抽屉完全关闭时显示.

但是,Gmail应用的行为有所不同.一旦抽屉打开任何数量,菜单项就会被隐藏.这是我想要的行为.有谁知道如何实现这一目标?

谢谢!

Nik*_*ski 47

你试过这个:

  1. invalidateOptionsMenu()通过测量滑动偏移,在您切换导航抽屉时使用.
  2. 迭代每个菜单项onPrepareOptionsMenu(Menu menu)并隐藏它.

    @Override
    
    public boolean onPrepareOptionsMenu(Menu menu) {
    
        // If the nav drawer is open, hide action items related to the content view
        boolean drawerOpen = shouldGoInvisible;
        hideMenuItems(menu, !drawerOpen);
        return super.onPrepareOptionsMenu(menu);
    }
    
    private void hideMenuItems(Menu menu, boolean visible)
    {
    
        for(int i = 0; i < menu.size(); i++){
    
            menu.getItem(i).setVisible(visible);
    
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

检测导航抽屉滑动的程度:

     mDrawerLayout.setDrawerListener(new DrawerListener(){
                    float mPreviousOffset = 0f;

        @Override
        public void onDrawerClosed(View arg0) {
                         super.onDrawerClosed(arg0);
                         shouldGoInvisible = false;
                         invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }

        @Override
        public void onDrawerOpened(View arg0) {
                         super.onDrawerOpened(arg0);
                         shouldGoInvisible = true;
                         invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }

        @Override
        public void onDrawerSlide(View arg0, float slideOffset) {
             super.onDrawerSlide(arg0, slideOffset);
             if(slideOffset > mPreviousOffset && !shouldGoInvisible){
                shouldGoInvisible = true;
                invalidateOptionsMenu();
            }else if(mPreviousOffset > slideOffset && slideOffset < 0.5f && shouldGoInvisible){
                shouldGoInvisible = false;
                invalidateOptionsMenu();
            }
            mPreviousOffset = slideOffset;


        }

        @Override
        public void onDrawerStateChanged(int arg0) {
            // or use states of the drawer to hide/show the items

        }});
Run Code Online (Sandbox Code Playgroud)

注意:shouldGoInvisible是类字段.


Eug*_*nec 5

如果您想在抽屉进入屏幕后立即覆盖操作栏并恢复操作栏,那么当前抽屉不再可见(截至2014年3月20日Gmail的行为方式),您可以使用以下代码:

mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
    R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {

  @Override
  public void onDrawerStateChanged(int newState) {
    super.onDrawerStateChanged(newState);

    boolean isOpened = mDrawerLayout.isDrawerOpen(mDrawerList);
    boolean isVisible = mDrawerLayout.isDrawerVisible(mDrawerList);

    if (!isOpened && !isVisible) {
      if (newState == DrawerLayout.STATE_IDLE) {
        // drawer just hid completely
        restoreActionBar();
      } else {
        // } else if (newState == DrawerLayout.STATE_SETTLING) {
        // drawer just entered screen
        overrideActionBar();
      }
    }
  }

  private void restoreActionBar() {
    getSupportActionBar().setTitle(mTitle);
    supportInvalidateOptionsMenu();
  }

  private void overrideActionBar() {
    getSupportActionBar().setTitle(mDrawerTitle);
    supportInvalidateOptionsMenu();
  }
};

// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
Run Code Online (Sandbox Code Playgroud)

根据您的需要修改restoreActionBar()overrideActionBar()方法.

无需区分滑动和主页按钮,也无需测量滑动长度.

变异

如果您不想引用抽屉列表视图,请使用以下代码:

    boolean isOpened = mDrawerLayout.isDrawerOpen(GravityCompat.START);
    boolean isVisible = mDrawerLayout.isDrawerVisible(GravityCompat.START);
Run Code Online (Sandbox Code Playgroud)

您可能希望使用,GravityCompat.END具体取决于您在XML布局中指定的内容.

编辑 - 关于行动

上面的示例不会隐藏与导航抽屉下方的内容相关的操作栏项.要在抽屉可见时执行此操作或显示不同的图标集,您必须手动跟踪抽屉是打开还是关闭.

除了上面的代码声明private boolean mDrawerVisible = false与适当的保存/恢复状态处理.然后修改mDrawerToggle内部方法如下:

  private void restoreActionBar() {
    getSupportActionBar().setTitle(mTitle);
    mDrawerVisible = false;
    supportInvalidateOptionsMenu();
  }

  private void overrideActionBar() {
    getSupportActionBar().setTitle(mDrawerTitle);
    mDrawerVisible = true;
    supportInvalidateOptionsMenu();
  }
Run Code Online (Sandbox Code Playgroud)

最后在onCreateOptionsMenu膨胀不同的菜单资源或onPrepareOptionsMenu显示/隐藏基于值的不同动作mDrawerVisible.