Clicking hamburger icon on Toolbar does not open Navigation Drawer

大城市里の小女人 提交于 2019-12-02 21:51:19

In your ActivityMain.xml, the toolbar is outside of the DrawerLayout. That's the problem. If you want Toolbar to interact with DrawLayout, Toolbar needs to be a child of DrawerLayout.

To fix the problem, make DrawerLayout the root of your activity. Here's the documentation. The relevant quote is:

To add a navigation drawer, declare your user interface with a DrawerLayout object as the root view of your layout. Inside the DrawerLayout, add one view that contains the main content for the screen (your primary layout when the drawer is hidden) and another view that contains the contents of the navigation drawer.

So basically, structure your ActivityMain.xml to be something like this:

<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>

That should take care of the problem.

You need to sync the drawer toggle:

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

EDIT: That code is working for me (copied from your post)

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>

But if you are using the new NavigationView, then you don't need the toggle etc. Here is a good example how to use it.

Amit

Override onOptionsItemSelected method and use below

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

If it helps somebody, to me it happened the same because of the stupid error of calling setSupportActionBar(toolbar) two times. Just call it once in onCreate method and never again. My mistake was I called it later in another method.

For the drawer toggle you need to set "display home as up" to false: getSupportActionBar().setDisplayHomeAsUpEnabled(false);

As i have no specific answer to your problem, i want to suggest a completely different approach:

In my projects im using the Material Drawer developed by Mike Penz. Its looks really nice, is easy to implement, and there is not much you have to worry about.

So if you cant find a solution for your problem, you could give it a try.

Use ActionBarDrawerToggle and implement public boolean onOptionsItemSelected(MenuItem item)

Toolbar DOES NOT have to be within a DrawerLayout, it's not likely to be the cause of this issue. toggle.onOptionsItemSelected(item) looks for the ID of the item selected and if it is android.R.id.home then the drawer's visibility is toggled. Thus Toolbar, or any View that creates a Home MenuItem, can be placed anywhere in your layout.

Within your activity:

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);
}

Simply call function onOptionsItemSelected(MenuItem menuItem) of ActionBarDrawerToggle class on activity options menu managing function like below.

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);
}

OR

override onOptionsItemSelected of activity like below

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);
    }
}

While accepted answer here works alright however, as they say "Prevention is better than cure".. Adding mDrawerToggle.syncState(); in onPostCreate and onConfigurationChanged() wroks much better as answerd by @mbmc above:

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

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    mDrawerToggle.onConfigurationChanged(newConfig);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!