Android 当导航抽屉滑动任意数量时隐藏ActionBar菜单项
我正在尝试实现一个导航抽屉,每当抽屉打开时,它都会隐藏ActionBar中的菜单项 我正在关注谷歌的文档,但是他们的代码并没有产生预期的行为 使用此代码,当抽屉完全打开时,菜单项隐藏,当抽屉完全关闭时,菜单项显示 然而,Gmail应用程序的表现却不同。只要抽屉打开任意数量,菜单项就会隐藏。这就是我想要的行为。有人知道如何做到这一点吗 谢谢 您是否尝试过以下方法:Android 当导航抽屉滑动任意数量时隐藏ActionBar菜单项,android,actionbarsherlock,navigation-drawer,Android,Actionbarsherlock,Navigation Drawer,我正在尝试实现一个导航抽屉,每当抽屉打开时,它都会隐藏ActionBar中的菜单项 我正在关注谷歌的文档,但是他们的代码并没有产生预期的行为 使用此代码,当抽屉完全打开时,菜单项隐藏,当抽屉完全关闭时,菜单项显示 然而,Gmail应用程序的表现却不同。只要抽屉打开任意数量,菜单项就会隐藏。这就是我想要的行为。有人知道如何做到这一点吗 谢谢 您是否尝试过以下方法: 通过测量滑动偏移量,在切换导航抽屉时使用invalidateOptions功能表() 在OnPrepareOptions菜单(菜单菜
invalidateOptions功能表()
OnPrepareOptions菜单(菜单菜单)
中的每个菜单项上迭代并隐藏它
@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);
}
}
@覆盖
公共布尔值OnPrepareOptions菜单(菜单){
//如果导航抽屉打开,则隐藏与内容视图相关的操作项
布尔值drawerropen=shouldGoInvisible;
hideMenuItems(菜单,!抽屉);
返回super.onPrepareOptions菜单(菜单);
}
私有void隐藏项(菜单菜单,布尔可见)
{
对于(int i=0;i
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
}});
mDrawerLayout.setDrawerListener(新的DrawerListener(){
浮点mPreviousOffset=0f;
@凌驾
公共无效onDrawerClosed(视图arg0){
super.onDrawerClosed(arg0);
shouldGoInvisible=false;
InvalidateOptions SMenu();//创建对OnPrepareOptions SMenu()的调用
}
@凌驾
已打开的公共void onDrawerOpened(视图arg0){
super.onDrawerOpened(arg0);
shouldGoInvisible=true;
InvalidateOptions SMenu();//创建对OnPrepareOptions SMenu()的调用
}
@凌驾
绘图滑块上的公共无效(视图arg0,浮动滑块偏移){
super.onDrawerSlide(arg0,slideOffset);
如果(滑动偏移>MPPreviousOffset&&!应可见){
shouldGoInvisible=true;
无效操作菜单();
}否则,如果(mPreviousOffset>slideOffset&&slideOffset<0.5f&&shouldGoInvisible){
shouldGoInvisible=false;
无效操作菜单();
}
MPPreviousOffset=滑动偏移;
}
@凌驾
公共无效onDrawerStateChanged(int arg0){
//或者使用抽屉的状态隐藏/显示项目
}});
注意:
应该是可见的
是类字段 我半同意尼古拉的观点,但只要在抽屉状态发生变化时更新图标就足够了
创建全局变量以跟踪抽屉状态:
private int mDrawerState;
设置新的抽屉式储物箱:
mDrawerLayout.setDrawerListener(new DrawerListener() {
@Override
public void onDrawerStateChanged(int state) {
mDrawerState = state;
invalidateOptionsMenu();
}
@Override
public void onDrawerSlide(View view, float slide) {
// TODO Auto-generated method stub
}
@Override
public void onDrawerOpened(View view) {
// TODO Auto-generated method stub
}
@Override
public void onDrawerClosed(View view) {
// TODO Auto-generated method stub
}
});
更新菜单可见性:
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawer);
for(int i=0;i<menu.size();i++){
// If the drawer is moving / settling or open do not draw the icons
menu.getItem(i).setVisible(mDrawerState!=DrawerLayout.STATE_DRAGGING &&
mDrawerState!=DrawerLayout.STATE_SETTLING && !drawerOpen);
}
boolean-drawerlayout=mDrawerLayout.isDrawerOpen(mDrawer);
对于(int i=0;i如果要隐藏所有菜单项,只需使用:
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
return showActionBarMenu; // boolean value, set it in drawer listeners as class variable
}
然后,您不需要看到每个菜单项。如果您想在抽屉进入屏幕后立即覆盖操作栏,并在抽屉不再可见时恢复操作栏(截至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);
根据需要修改restoreActionBar()
和overrideActionBar()
方法
不需要区分滑动和主页按钮,也不需要测量滑动长度
变异
如果不想引用抽屉列表视图,请使用以下代码:
boolean isOpened = mDrawerLayout.isDrawerOpen(GravityCompat.START);
boolean isVisible = mDrawerLayout.isDrawerVisible(GravityCompat.START);
您可能希望使用GravityCompat.END
,这取决于您在XML布局中指定的内容
编辑-有关操作
上面的示例没有隐藏与导航抽屉下的内容相关的操作栏项目。要这样做或在抽屉可见时显示不同的图标集,您必须跟踪抽屉是手动打开还是关闭的
除上述代码外,通过正确的保存/还原状态处理声明专用布尔值mdrawerible=false
。
然后修改mDrawerToggle
内部方法,如下所示:
private void restoreActionBar() {
getSupportActionBar().setTitle(mTitle);
mDrawerVisible = false;
supportInvalidateOptionsMenu();
}
private void overrideActionBar() {
getSupportActionBar().setTitle(mDrawerTitle);
mDrawerVisible = true;
supportInvalidateOptionsMenu();
}
最后,在onCreateOptions菜单中
膨胀不同的菜单资源,或者在onPrepareOptions菜单中
根据mdrawerible
的值显示/隐藏不同的操作,我接受了@Laurence Dawson的答案,并对其进行了简化。此解决方案不需要使用任何类成员
在onCreate()期间执行此代码:
并覆盖此方法:
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
boolean actionsVisibility = !drawerLayout.isDrawerVisible(Gravity.START);
for(int i=0;i<menu.size();i++){
menu.getItem(i).setVisible(actionsVisibility);
}
return super.onPrepareOptionsMenu(menu);
}
@覆盖
公共布尔值OnPrepareOptions菜单(菜单){
抽屉布局抽屉布局=(抽屉布局)findViewById(R.id.drawer\U布局);
布尔操作可视性=!drawerLayout.isDrawervible(Gravity.START);
对于(int i=0;i我对这个问题有一个更好的解决方案:
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (navigationDrawerFragment.isDrawerOpen()) {
menu.clear();
}
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!navigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
showLocalContextActionBar();
return false;
}
return super.onCreateOptionsMenu(menu);
}
我有不同的代码,但解决方案相同:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
hideMenuItems(menu, !mShouldGoInvisible);
return super.onCreateOptionsMenu(menu);
}
private void hideMenuItems(Menu menu, boolean visible){
for(int i = 0; i < menu.size(); i++){
menu.getItem(i).setVisible(visible);
}
}
是的,这基本上就是我正在做的。问题是,直到抽屉完全打开,代码才会被调用,而不是像Gmail中一样,抽屉一打开,甚至一点点。我在onDrawerOpen()和onDrawerClose()中调用SupportInvalidateOptions菜单()我的ActionBarDrawerToggle对象。@Synergy807我已经测试过了,它可以像你期望的那样完美地工作。无论抽屉在任何方向上滑动多少次,它都会隐藏抽屉。谢谢你的帮助!onDrawerSlide和OnDrawerState方法在我需要的地方改变了。应该看到的是一个类字段。你能展示它是如何定义的吗?private boolean shouldGoInvisible=false;
谢谢,这与我最终的做法非常相似!事实上,在进一步调查之后,我发现使用状态并不太有效,至少在我的实现中是如此。如果你只是
@Override
public boolean onCreateOptionsMenu(Menu menu) {
hideMenuItems(menu, !mShouldGoInvisible);
return super.onCreateOptionsMenu(menu);
}
private void hideMenuItems(Menu menu, boolean visible){
for(int i = 0; i < menu.size(); i++){
menu.getItem(i).setVisible(visible);
}
}
@Override
public void onNavigationDrawerListener(boolean opened, int position) {
if (opened){
mShouldGoInvisible = true;
invalidateOptionsMenu();
} else {
mShouldGoInvisible = false;
invalidateOptionsMenu();
}
}