Android 如何检测 DrawerLayout 开始打开?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23373257/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to detect that the DrawerLayout started opening?
提问by Oleksiy
So I have tabs that I want to hide when the Navigation Drawer startsopening. The code I have hides them when it finished opening, but it's not what I want.
因此,当导航抽屉开始打开时,我想隐藏一些选项卡。我的代码在完成打开时隐藏了它们,但这不是我想要的。
mDrawerToggle = new ActionBarDrawerToggle(
this,
mDrawerLayout,
R.drawable.ic_drawer,
R.string.drawer_open,
R.string.drawer_close
) {
@Override
public void onDrawerClosed(View view) {
invalidateOptionsMenu();
setActionBarMode(ActionBar.NAVIGATION_MODE_TABS);
}
@Override
public void onDrawerOpened(View drawerView) {
invalidateOptionsMenu();
setActionBarMode(ActionBar.NAVIGATION_MODE_STANDARD);
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
Here's what I tried:
这是我尝试过的:
- Setting an
onClickListener
tomDrawerLayout
.onClick
never gets called - Setting an
onTouchListener
tomDrawerLayout
.onTouch
never gets called - Researched
ActionBarDrawerToggle
andDrawerLayout
classes. Could not find anything likeonDrawerStartedOpening
.
- 设置
onClickListener
为mDrawerLayout
。onClick
永远不会被调用 - 设置
onTouchListener
为mDrawerLayout
。onTouch
永远不会被调用 - 研究
ActionBarDrawerToggle
和DrawerLayout
上课。找不到类似的东西onDrawerStartedOpening
。
回答by Pavel Dudka
There are 2 possible ways to do that:
有两种可能的方法来做到这一点:
1) Use onDrawerSlide(View drawerView, float slideOffset)
callback
1)使用onDrawerSlide(View drawerView, float slideOffset)
回调
slideOffset
changes from 0 to 1. 1
means it is completely open, 0
- closed.
slideOffset
从 0 变为 1。1
表示它完全打开,0
- 关闭。
Once offset changes from 0
to !0
- it means it startedopening process. Something like:
一旦偏移量从0
到!0
- 这意味着它开始打开过程。就像是:
mDrawerToggle = new ActionBarDrawerToggle(
this,
mDrawerLayout,
R.drawable.ic_drawer,
R.string.drawer_open,
R.string.drawer_close
) {
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
if (slideOffset == 0
&& getActionBar().getNavigationMode() == ActionBar.NAVIGATION_MODE_STANDARD) {
// drawer closed
getActionBar()
.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
invalidateOptionsMenu();
} else if (slideOffset != 0
&& getActionBar().getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS) {
// started opening
getActionBar()
.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
invalidateOptionsMenu();
}
super.onDrawerSlide(drawerView, slideOffset);
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
2) Use onDrawerStateChanged(int newState)
callback
2)使用onDrawerStateChanged(int newState)
回调
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:
您需要监听STATE_SETTLING
状态 - 每当抽屉开始移动(打开或关闭)时都会报告此状态。因此,一旦您看到此状态 - 检查抽屉现在是否已打开并采取相应措施:
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);
回答by Kirill Karmazin
Currently accepted answer by Pavel Dudka is already deprecated.
Please use mDrawerLayout.addDrawerListener()
method instead to set a listener.
Pavel Dudka 目前接受的答案已被弃用。请改用mDrawerLayout.addDrawerListener()
方法来设置侦听器。
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
//Called when a drawer's position changes.
}
@Override
public void onDrawerOpened(View drawerView) {
//Called when a drawer has settled in a completely open state.
//The drawer is interactive at this point.
// If you have 2 drawers (left and right) you can distinguish
// them by using id of the drawerView. int id = drawerView.getId();
// id will be your layout's id: for example R.id.left_drawer
}
@Override
public void onDrawerClosed(View drawerView) {
// Called when a drawer has settled in a completely closed state.
}
@Override
public void onDrawerStateChanged(int newState) {
// Called when the drawer motion state changes. The new state will be one of STATE_IDLE, STATE_DRAGGING or STATE_SETTLING.
}
});
Works perfectly. Cheers!
完美运行。干杯!
回答by fookwood
try to override a method of DrawerLayout.DrawerListener
尝试覆盖 DrawerLayout.DrawerListener 的方法
@Override
public void onDrawerStateChanged(int newState) {
if( newState == DrawerLayout.STATE_DRAGGING && isDrawerOpen() == false ) {
// this where Drawer start opening
}
}
回答by NoHarmDan
Up-to-date solution:
最新解决方案:
As others have suggested, the current answer is outdated and it's advised to use mDrawerLayout.addDrawerListener()
. A working solution would then be:
正如其他人所建议的那样,当前的答案已经过时,建议使用mDrawerLayout.addDrawerListener()
. 一个可行的解决方案是:
mDrawerLayout.addDrawerListener(new DrawerLayout.SimpleDrawerListener() {
@Override
public void onDrawerStateChanged(int newState) {
if (newState == DrawerLayout.STATE_SETTLING && !mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
// Drawer started opening
}
}
});
Naturally, replace GravityCompat.START
with whatever identifies your drawer (layout ID or its gravity ~ location).
自然地,GravityCompat.START
用任何标识你的抽屉的东西(布局 ID 或它的重力 ~ 位置)替换。
Also, if you want to detect when the drawer starts closing, you can simply do:
此外,如果您想检测抽屉何时开始关闭,您可以简单地执行以下操作:
mDrawerLayout.addDrawerListener(new DrawerLayout.SimpleDrawerListener() {
@Override
public void onDrawerStateChanged(int newState) {
if (newState == DrawerLayout.STATE_SETTLING) {
if (!mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
// Drawer started opening
} else {
// Drawer started closing
}
}
}
});
回答by Kishan Solanki
For Kotlin
对于科特林
var toggle = object : ActionBarDrawerToggle(this,
drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
override fun onDrawerOpened(drawerView: View) {
super.onDrawerOpened(drawerView)
}
}
drawer_layout.addDrawerListener(toggle)
toggle.syncState()
回答by Stefano Cristoni
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close){
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
app.sendScreenView("Menu");
}
};
drawer.setDrawerListener(toggle);
toggle.syncState();
It's the best way.
这是最好的方法。
回答by bastami82
fookwood answer did not work for me but slight modification in the if statment did the trick)
fookwood 的答案对我不起作用,但在 if 语句中稍作修改即可解决问题)
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, navigationDrawerLayout, topToolbar,
R.string.open_drawer, R.string.close_drawer) {
@Override public void onDrawerStateChanged(int newState) {
if (newState == DrawerLayout.STATE_SETTLING && !navigationDrawerLayout.isDrawerOpen(navigationDrawerView)) {
// this where Drawer start opening
}