点击工具栏上的汉堡图标无法打开导航抽屉。

49

我有一个简单的 android.support.v7.widget.Toolbar,我正在尝试做的就是通过按左上角的“汉堡包”图标来打开导航抽屉。 “汉堡包”按钮可见,并且当我开始从左侧拉时,我可以看到按钮上的动画,但按下按钮不会像我期望的那样打开/关闭导航抽屉。我已经遵循了[Google文档][1],但仍然无法弄清楚。对此表示抱歉,以下是我目前正在尝试使用的简化代码:

public class MainActivity extends AppCompatActivity implements
    View.OnClickListener,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener {



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    setContentView(R.layout.activity_main);


    Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);



    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("NICK", "button button button..................");
        }
    });

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
        NavigationView n = (NavigationView) findViewById(R.id.nav);
        mDrawerLayout.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Log.d("NICK", "button button button..................");
            }
        });

        //mDrawerLayout.setDrawerListener(mDrawerToggle);
        n.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {
                switch (menuItem.getItemId()) {
                    ////.......

                }
                mDrawerLayout.closeDrawers();  // CLOSE DRAWER
                return true;
            }
        });

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    Log.d("NICK","CWECNEWKVNERIPNVIEWNFVIPEWNVIPEWNVPIEWNVPIEWNVPIEWNVPIRWNVPRWVPO");
    switch (item.getItemId()) {
        case android.R.id.home:
            mDrawerLayout.openDrawer(GravityCompat.START);  // OPEN DRAWER
            Log.d("NICK","CWECNEWKVNERIPNVIEWNFVIPEWNVIPEWNVPIEWNVPIEWNVPIEWNVPIRWNVPRWVPO");
            return true;

    }
           return super.onOptionsItemSelected(item);


}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    mDrawerToggle.onConfigurationChanged(newConfig);
}



@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.drawer, menu);
    return true;
}


}

}

我运行时没有看到任何日志调试语句。

这基本上就是我的问题:https://dev59.com/NF8d5IYBdhLWcg3wpzlf#26636045。我已经按照这个做了,但它就是不起作用。

据我所知,当按下汉堡图标时,将调用setNavigationOnClickListener,我现在专注于正确处理该事件,因为当我按下按钮时,我无法获取我的日志语句。如果这个想法是不正确的,请让我知道。https://developer.android.com/reference/android/widget/Toolbar.html#setNavigationOnClickListener(android.view.View.OnClickListener)

我的布局:

ActivityMain.xml

<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/d"
android:background="@drawable/home_wall">




<android.support.v7.widget.Toolbar
    android:id="@+id/my_toolbar"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:layout_marginBottom="10dp"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    android:layout_marginTop="25dp"

    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto" />



<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:id="@+id/drawer"

    android:layout_height="match_parent"
    android:fitsSystemWindows="true">



    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="200dp"
        android:id="@+id/imageView"
        android:src="@drawable/trans2"
        android:layout_alignParentTop="true"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:paddingBottom="300dp" />

    <RelativeLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/d8"
        android:layout_alignParentTop="true"
        android:layout_alignLeft="@+id/imageView"
        android:layout_alignStart="@+id/imageView"
        android:paddingTop="0dp">

        <Button
            android:layout_width="75dp"
            android:layout_height="50dp"
            android:text="Gallery"
            android:id="@+id/save_button"
            android:background="#dd2c00" android:textColor="#fff"
            android:layout_below="@+id/Purchases"
            android:layout_toRightOf="@+id/start_button"
            android:layout_toEndOf="@+id/start_button" />
        <Button
            android:layout_width="125dp"
            android:layout_height="50dp"
            android:text="Store"
            android:id="@+id/Purchases"
            android:background="#ff6e40" android:textColor="#fff"
            android:layout_above="@+id/instructions_button6"
            android:layout_toLeftOf="@+id/start_button"
            android:layout_toStartOf="@+id/start_button"
            android:layout_marginBottom="98dp" />
        <Button
            android:layout_width="75dp"
            android:layout_height="50dp"
            android:text="Help"
            android:id="@+id/instructions_button6"
            android:background="#dd2c00" android:textColor="#fff"
            android:layout_alignParentBottom="true"
            android:layout_toLeftOf="@+id/start_button"
            android:layout_toStartOf="@+id/start_button"
            android:layout_marginLeft="5dp"
            android:layout_marginBottom="10dp" />
        <Button
            android:layout_width="75dp"
            android:layout_height="300dp"
            android:text="Start"
            android:id="@+id/start_button"
            android:background="#ff3d00"
            android:textColor="#fff"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="10dp" />
        <Button
            android:layout_width="125dp"
            android:layout_height="50dp"
            android:text="Achievements"
            android:id="@+id/Scores"
            android:background="#ff6e40" android:textColor="#fff"
            android:layout_alignTop="@+id/Purchases"
            android:layout_toRightOf="@+id/start_button"
            android:layout_toEndOf="@+id/start_button" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Welcome to the quiz!"
            android:id="@+id/textView"
            android:textColor="#fff"
            android:textSize="20dp"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="70dp" />


        <!-- sign-in button -->
        <com.google.android.gms.common.SignInButton
            android:id="@+id/sign_in_button"
            android:layout_width="110dp"
            android:layout_height="50dp"
            android:layout_above="@+id/start_button"
            android:layout_centerHorizontal="true"
            android:visibility="visible" />

        <!-- sign-out button -->
        <Button
            android:id="@+id/sign_out_button"
            android:layout_width="125dp"
            android:layout_height="wrap_content"
            android:text="Sign Out"
            android:visibility="invisible"
            android:background="#dd4b39"
            android:textColor="#fff"
            android:layout_alignTop="@+id/sign_in_button"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="160dp" />

    </RelativeLayout>

    <android.support.design.widget.NavigationView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#fff"
        android:id="@+id/nav"

        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/drawer"/>
</android.support.v4.widget.DrawerLayout>
< p >抽屉布局.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_menu"
xmlns:app="http://schemas.android.com/apk/res-auto">

<item android:title="Google Play Games"

    android:icon="@drawable/ic_local_airport_white_48dp">
    <menu>
        <item
            android:id="@+id/Sign_in_drawer"

            android:icon="@drawable/games_controller_grey"
            android:title="Sign in" />
        <item
            android:id="@+id/ach"
            android:icon="@drawable/games_achievements"
            android:title="Achievements" />
    </menu>
</item>

<item android:title="Start a Quiz"

   android:icon="@drawable/ic_local_airport_white_48dp">
    <menu>
        <item
            android:id="@+id/quizStart25"

            android:icon="@drawable/ic_local_airport_white_48dp"
            android:title="25 Questions" />
        <item
            android:id="@+id/quizStart10"
            android:icon="@drawable/ic_local_airport_white_48dp"
            android:title="10 Questions" />
    </menu>
</item>

<group
    android:checkableBehavior="single">
    <item
        android:id="@+id/gallery"

        android:icon="@drawable/ic_photo_library_white_48dp"
        android:title="Gallery" />
    <item
        android:id="@+id/stats"
        android:icon="@drawable/ic_toc_white_48dp"
        android:title="Statistics" />
    <item
        android:id="@+id/store"
        android:icon="@drawable/ic_shop_white_48dp"
        android:title="Store" />
    <item
        android:id="@+id/settings"
        android:icon="@drawable/ic_settings_white_48dp"
        android:title="Settings" />
    <item
        android:id="@+id/about"
        android:icon="@drawable/ic_info_white_48dp"
        android:title="About" />

</group>

<item android:title="Support">
    <menu>
        <item
            android:id="@+id/help_drawer"
            android:icon="@drawable/ic_help_white_48dp"
            android:title="Help" />
        <item
            android:id="@+id/report"
            android:icon="@drawable/ic_report_problem_white_48dp"
            android:title="Contact Developer" />
        <item
            android:id="@+id/GPlusCommunity"
            android:icon="@drawable/btn_g_white_normal"
            android:title="Google+ Community" />

    </menu>
</item>

17个回答

98

在ActivityMain.xml文件中,工具栏(toolbar)在DrawerLayout之外。这就是问题所在。如果你想让Toolbar与DrawLayout交互,Toolbar需要成为DrawerLayout的子元素。

要解决这个问题,请将DrawerLayout设置为您活动的根布局。 这里是相关的文档。引用如下:

要添加导航抽屉,请使用DrawerLayout对象声明用户界面作为布局的根视图。在DrawerLayout内,添加一个视图,其中包含屏幕的主要内容(在隐藏抽屉时的主要布局)和另一个视图,其中包含导航抽屉的内容。

所以基本上,将ActivityMain.xml结构化为类似于以下内容:

<android.support.v4.widget.DrawerLayout ...>

    <RelativeLayout ...>

        <android.support.v7.widget.Toolbar .../>

        <!-- Your other content goes here -->

    </RelativeLayout>

    <android.support.design.widget.NavigationView .../>

</android.support.v4.widget.DrawerLayout>

那应该能解决问题了。


我已经尝试过这个方法,甚至在onOptionsItemSelected方法内部插入了日志语句,但它们从未显示出来,表明该方法从未被调用。现在我的onOptionsItemSelected方法在onCreate方法之外,如果有影响的话。仍然没有找到解决方案。 - ez4nick
1
我正在扩展 AppCompatActivity - ez4nick
你运行了我发布的确切代码吗?请确保你复制的是完全一样的,而不是修改或附加到现有的代码中。我已经运行了发布的代码,它可以正常工作。此外,当单击汉堡图标时,我看到那些日志行。如果你运行了这个“确切”的代码,但仍然无法工作,那么恐怕我不能再提供更多帮助了。因为这真的是标准的导航抽屉内容,所以你的项目肯定存在一些非常奇怪的问题。 - hungryghost
我刚刚运行了你发布的完全相同的代码,并且得到了与之前完全相同的结果,日志语句没有出现。这可能是一个更复杂的问题,也许与Android Studio有关。再次感谢你的帮助。 - ez4nick
@ez4nick,最后一个问题。你能否发布你的xml布局和菜单?也许那里有什么问题。具体而言,请发布包含R.id.my_toolbar、R.id.drawer和R.id.nav的布局,然后发布你的菜单R.menu.drawer。 - hungryghost
显示剩余5条评论

30

覆盖onOptionsItemSelected方法并使用以下内容

if(item.getItemId() == android.R.id.home){ // use android.R.id
    mDrawerLayout.openDrawer(Gravity.LEFT);
}

10

您需要同步抽屉切换:

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    // Sync the toggle state after onRestoreInstanceState has occurred.
    mDrawerToggle.syncState();
}

编辑:那段代码对我有效(从您的帖子中复制)

public class TempActivity extends AppCompatActivity {
    private ActionBarDrawerToggle mDrawerToggle;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.temp);
        setupDrawer();
    }
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }
    @Override
    public boolean onOptionsItemSelected(final MenuItem item) {
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        mDrawerToggle.syncState();
    }
    private void setupDrawer() {
        Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
        DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.my_drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,toolbar,R.string.drawer_open, R.string.drawer_close) {
            public void onDrawerClosed(View view) {
                super.onDrawerClosed(view);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }
        };
        mDrawerLayout.setDrawerListener(mDrawerToggle);
    }
}

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/my_drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <android.support.v7.widget.Toolbar
            android:id="@+id/my_toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
        <FrameLayout
            android:id="@+id/content_frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>
    <RelativeLayout
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#FFF"
            android:text="DRAMER MENU" />
    </RelativeLayout>
</android.support.v4.widget.DrawerLayout>

但是如果您正在使用新的NavigationView,那么您就不需要切换等功能了。这是一个很好的例子,告诉您如何使用它。


我正在使用新的“NavigationView”,并尝试按照您提供的链接(见更新2)进行操作,但从未收到确认按钮已被按下的信息。我认为这就是导航抽屉实际上被打开/关闭的位置。 - ez4nick
那么就不需要设置 ActionBarDrawerToggle - mbmc

9

我通过将可打开的drawerLayout提供给navigateUp函数来解决了这个问题。

更多信息请参考navigateUp文档

 override fun onSupportNavigateUp(): Boolean {
    val navController = this.findNavController(R.id.host_fragment)
    return NavigationUI.navigateUp(navController,drawer_layout)
}

你好,欢迎来到 Stackoverflow!能否在你的答案中加入一些解释呢?这样人们就能知道为什么会在你的代码中起作用了。 - Martin Paucot
2
是的,问题解决了。我删除了由Android Studio自动添加的方法,汉堡图标停止工作了,重新添加它解决了问题。 - acmpo6ou

6
如果有帮助的话,我也因为愚蠢的错误调用了setSupportActionBar(toolbar)两次而遇到了同样的问题。只需在onCreate方法中调用一次,以后再也不要调用了。我的错误是我在另一个方法中后来又调用了它。

4

使用 ActionBarDrawerToggle 并实现 public boolean onOptionsItemSelected(MenuItem item)

Toolbar 不必在 DrawerLayout 中,它不太可能是此问题的原因。 toggle.onOptionsItemSelected(item) 查找所选项目的 ID,如果是 android.R.id.home,则切换抽屉的可见性。 因此 Toolbar 或任何创建 Home MenuItem 的视图都可以放置在布局中的任何位置。

在您的活动内:

ActionBarDrawerToggle toggle;

private void setupDrawerToggleInActionBar() {
    // assuming a Toolbar has been initialized in your onCreate
    this.setSupportActionBar(toolbar);

    // setup the action bar properties that give us a hamburger menu
    ActionBar actionBar = this.getSupportActionBar();
    if(actionBar != null) {
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setHomeButtonEnabled(true);
    }

    // the toggle allows for the simplest of open/close handling
    toggle = new ActionBarDrawerToggle(this,
                                       drawerLayout,
                                       R.string.navigation_drawer_open,
                                       R.string.navigation_drawer_close);
    // drawerListener must be set before syncState is called
    drawerLayout.setDrawerListener(toggle);

    toggle.setDrawerIndicatorEnabled(true);
    toggle.syncState();
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    // This is required to make the drawer toggle work
    if(toggle.onOptionsItemSelected(item)) {
        return true;
    }

    /*
     * if you have other menu items in your activity/toolbar 
     * handle them here and return true
     */

    return super.onOptionsItemSelected(item);
}

2
只需在活动选项菜单管理函数中调用ActionBarDrawerToggle类的onOptionsItemSelected(MenuItem menuItem)函数,如下所示。
mDrawerToggle= new ActionBarDrawerToggle(activity, drawerLayout, R.string.nav_drawer_accessbility_drawer_open,
            R.string.nav_drawer_accessbility_drawer_close);


 @Override
public boolean onOptionsItemSelected(final android.view.MenuItem item) {
    navigation().getOptionsMenuInflater(this).closeSearchView();
    // The action bar home/up action should open or close the drawer.
    // ActionBarDrawerToggle will take care of this behavior.
    mDrawerToggle.onOptionsItemSelected(item);

    return super.onOptionsItemSelected(item);
}

覆盖活动的onOptionsItemSelected方法如下:

public boolean onOptionsItemSelected(MenuItem item) {
    if (item != null && item.getItemId() == android.R.id.home) {
        toggle();

    }
    return super.onOptionsItemSelected(item);
}

 private void toggle() {
    if (mDrawerLayout.isDrawerVisible(GravityCompat.START)) {
        mDrawerLayout.closeDrawer(GravityCompat.START);
    } else {
        mDrawerLayout.openDrawer(GravityCompat.START);
    }
}

1

对于抽屉开关,你需要将 "显示主页为向上" 设置为 false: getSupportActionBar().setDisplayHomeAsUpEnabled(false);


3
尝试过这个方法,但没有解决我的问题。和之前遇到的问题一样。 - ez4nick

1

由于我没有对您的问题给出具体答案,我想建议一个完全不同的方法:

在我的项目中,我使用了Mike Penz开发的Material Drawer。它看起来非常漂亮,易于实现,而且你不需要太担心。

因此,如果您找不到解决方案,可以尝试一下。


1
首先,按照被接受的答案提供的指示进行操作。
然后,确保为切换指定正确的构造函数 - 即,
val toggle = ActionBarDrawerToggle(this, binding.root, toolbar, R.string.OpenDrawer, R.string.CloseDrawer)
drawerLayout.addDrawerListener(toggle)
toggle.syncState()

当 drawerLayout 是 val drawerLayout = findViewById(R.id.drawer)

由于 ActionBarDrawerToggle() 有两种构造函数类型

1 - ActionBarDrawerToggle(
    Activity activity,
    DrawerLayout drawerLayout,
    @StringRes int openDrawerContentDescRes,
    @StringRes int closeDrawerContentDescRes
)

2- ActionBarDrawerToggle(
    Activity activity,
    DrawerLayout drawerLayout,
    Toolbar toolbar,
    @StringRes int openDrawerContentDescRes,
    @StringRes int closeDrawerContentDescRes
)

使用第二个选项将切换分配给您的工具栏
您可以在这里阅读官方文档。

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