打开 DrawerLayout 前的事件

4

我认为DrawerLayout实现中缺少一个关键点:在抽屉打开之前触发的事件。

drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {
  public void onDrawerClosed(View view) {
    //...
  }

  public void onBeforeDrawerOpened(View drawerView) {
    //...
  }

  public void onDrawerOpened(View drawerView) {
    //...
  }
};

需要它的原因是设置抽屉项目的状态,比如选择的菜单项目、启用和类似的状态。将其放入 onDrawerOpened() 回调函数中有点可行,但在打开后改变菜单外观并不是很合适。
我的第一个想法是扩展 ActionBarDrawerToggle 并提供新事件。我应该重新发明轮子吗 :-) ,还是已经有人做过了?

1
补充说明:我想到可以在 newState == DrawerLayout.STATE_DRAGGING 时使用 onDrawerStateChanged(),但它似乎在两个方向上都被调用,即使抽屉关闭时也是如此。 - Gábor
4个回答

8

这个链接可以帮助你解决问题。 如何检测DrawerLayout何时开始打开?

Use onDrawerStateChanged(int newState) callback

You need to listen to STATE_SETTLING states - this state is reported whenever drawer starts moving (either opens or closes). So once you see this state - check whether drawer is opened now and act accordingly:

    mDrawerToggle = new ActionBarDrawerToggle(
        this,                 
        mDrawerLayout,        
        R.drawable.ic_drawer,  
        R.string.drawer_open,  
        R.string.drawer_close  
) {
    @Override
    public void onDrawerStateChanged(int newState) {
        if (newState == DrawerLayout.STATE_SETTLING) {
            if (!isDrawerOpen()) {
                // starts opening
                getActionBar()
                        .setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
            } else {
                // closing drawer
                getActionBar()
                        .setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
            }
            invalidateOptionsMenu();
        }
    }
};
mDrawerLayout.setDrawerListener(mDrawerToggle);

3
我在谷歌上找到了这个答案,当我遇到这个问题并没有在任何地方找到确切的答案,所以我决定发布完整的答案。希望能为某些人节省时间。
我发现最好的解决方法是监控抽屉状态,并使用isDrawerOpen方法确定它是正在打开还是关闭。请确保将重力设置为与打开/关闭抽屉时使用的重力匹配。
DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
// ...
ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_playlist, R.string.drawer_open, R.string.drawer_close) {
    public void onDrawerStateChanged(int newState) {
        if(newState == DrawerLayout.STATE_DRAGGING){
            if(mDrawerLayout.isDrawerOpen(Gravity.LEFT)){
                //closing

            }else{
                //opening

            }
        }
    }
}

0

结合 Lenny 和 Fred 的答案,针对 Kotlin:

    var toggle = object : ActionBarDrawerToggle(this,
    drawer_layout, toolbar, R.string.drawer_open, R.string.drawer_close) {

        override fun onDrawerStateChanged(newState: Int) {
            super.onDrawerStateChanged(newState)

            if(newState == DrawerLayout.STATE_SETTLING){
                if(drawer_layout.isDrawerOpen(Gravity.LEFT)){
                    //closing
                }else{
                    //opening
                }
            }
        }
    }
    drawer_layout.addDrawerListener(toggle)
    toggle.syncState()

0

在被接受的答案中推荐使用的setDrawerListener方法现已弃用。现在做这件事的新方法是使用addDrawerListener方法。

Kotlin中:

  1. 初始化DrawerLayout视图

    val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)

  2. 在您的主活动中,创建一个内部类,它是DrawerLayout.DrawerListener的子类。DrawerLayout类实现了DrawerListener接口。您可以在onDrawerSlide中跟踪抽屉位置的变化,并确定抽屉是打开还是关闭:

    inner class CustomDrawer : DrawerLayout.DrawerListener{
      override fun onDrawerStateChanged(newState: Int) {
      }
    
    var last: Float = 0f
    
    override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
        imm.hideSoftInputFromWindow(drawerView?.getWindowToken(), 0)
    
        var opening: Boolean = slideOffset>last
        var closing: Boolean = slideOffset<last
    
        if(opening) {
            Log.i("Drawer","opening")
            Log.d("Last",last.toString())
        } else if(closing) {
            Log.i("Drawer","closing")
            Log.d("Last",last.toString())
        } else {
            Log.i("Drawer","doing nothing")
            Log.d("Last",last.toString())
        }
    }
    
    override fun onDrawerClosed(drawerView: View) {
    
      }
    
    override fun onDrawerOpened(drawerView: View) {
    
      }
    }
    
  3. 将自定义DrawerListener添加到drawerLayout中(我将其放在onCreate方法中)

    var drawerListener = CustomDrawer()
    drawerLayout.addDrawerListener(drawerListener)
    

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