128

Yesterday (17-10-2014) I have update Android SDK and support-library-v4.jar of my App, now I get deprecation warning related to ActionBarDrawerToggle, reading the documentation seems that I have to use the ActionBarDrawerToggle in support-library-v7.appcompact.jar.

Here some parts of my Activity that could be relevants:

import android.app.ActionBar;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.webkit.WebView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;


public class MyActivity extends FragmentActivity {
    private ActionBar bar;
    private CustomActionBarDrawerToggle mDrawerToggle;
    private DrawerLayout mDrawer;
    private ListView mDrawerList;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_infoviewer);

        bar = this.getActionBar();

        bar.setDisplayHomeAsUpEnabled(true);

        bar.setHomeButtonEnabled(true);
        bar.setDisplayShowTitleEnabled(false);
        mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);

        mDrawer.setBackgroundColor(getResources().getColor(R.color.White));
        initNavMenu();
        try {
            mDrawerToggle = new CustomActionBarDrawerToggle(this, mDrawer);
        } catch (RuntimeException e) {
            e.printStackTrace();
        }

        mDrawer.setDrawerListener(mDrawerToggle);
    }

    ....

    private void initNavMenu() {
        NavMenuAdapter mAdapter = MyDrawers.getDefaultDrawer(MyActivity.this, true);
        mDrawerList = (ListView) findViewById(R.id.drawer);
        mDrawerList.setBackgroundColor(getResources().getColor(R.color.GreenMoneyDark));
        if (mDrawerList != null) mDrawerList.setAdapter(mAdapter);
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener(MyActivity.this, mDrawer, mDrawerList));
    }

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

    private class CustomActionBarDrawerToggle extends ActionBarDrawerToggle {

        public CustomActionBarDrawerToggle(Activity mActivity,
                                           DrawerLayout mDrawerLayout) {
            super(mActivity, mDrawerLayout, R.drawable.action_drawer,
                    R.string.ns_menu_open, R.string.ns_menu_close);
        }

        @Override
        public void onDrawerClosed(View view) {
            bar.setTitle(getString(R.string.ns_menu_close));
            invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }

        @Override
        public void onDrawerOpened(View drawerView) {
            bar.setTitle(getString(R.string.ns_menu_open));
            invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }
    }

}

I have tried to copy support-library-v7 and replace

import android.support.v4.app.ActionBarDrawerToggle;

with

 import android.support.v7.app.ActionBarDrawerToggle;

this has caused compilation problem in

 public CustomActionBarDrawerToggle(Activity mActivity,
                                               DrawerLayout mDrawerLayout) {
                super(mActivity, mDrawerLayout, R.drawable.action_drawer,
                        R.string.ns_menu_open, R.string.ns_menu_close);
            }

So I have tried to replace R.drawable.action_drawer with

public CustomActionBarDrawerToggle(Activity mActivity,
                                           DrawerLayout mDrawerLayout) {
            super(mActivity, mDrawerLayout,new Toolbar(MyActivity.this) ,
                    R.string.ns_menu_open, R.string.ns_menu_close);
        }

this compiles but crash at Runtime with

 java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v7/appcompat/R$attr;
            at android.support.v7.widget.Toolbar.<init>(Toolbar.java:190)
            at android.support.v7.widget.Toolbar.<init>(Toolbar.java:186)

Note that android-support-v7-appcompat.jar is correctly added in project dependencies enter image description here

AndreaF
  • 11,975
  • 27
  • 102
  • 168

4 Answers4

66

Adding only android-support-v7-appcompat.jar to library dependencies is not enough, you have also to import in your project the module that you can find in your SDK at the path \android-sdk\extras\android\support\v7\appcompatand after that add module dependencies configuring the project structure in this way

enter image description here

otherwise are included only the class files of support library and the app is not able to load the other resources causing the error.

In addition as reVerse suggested replace this

public CustomActionBarDrawerToggle(Activity mActivity,
                                           DrawerLayout mDrawerLayout) {
            super(mActivity, mDrawerLayout,new Toolbar(MyActivity.this) ,
                    R.string.ns_menu_open, R.string.ns_menu_close);
        }

with

public CustomActionBarDrawerToggle(Activity mActivity,
                                           DrawerLayout mDrawerLayout) {
            super(mActivity, mDrawerLayout, R.string.ns_menu_open, R.string.ns_menu_close);
        }
Silverstorm
  • 15,398
  • 2
  • 38
  • 52
60

There's no need for you to use super-call of the ActionBarDrawerToggle which requires the Toolbar. This means instead of using the following constructor:

ActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, Toolbar toolbar, int openDrawerContentDescRes, int closeDrawerContentDescRes)

You should use this one:

ActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, int openDrawerContentDescRes, int closeDrawerContentDescRes)

So basically the only thing you have to do is to remove your custom drawable:

super(mActivity, mDrawerLayout, R.string.ns_menu_open, R.string.ns_menu_close);

More about the "new" ActionBarDrawerToggle in the Docs (click).

reVerse
  • 35,075
  • 22
  • 89
  • 84
  • I have tried to follow your suggestion but crashes with this issue:`java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v7/appcompat/R$styleable; at android.support.v7.app.DrawerArrowDrawable.(DrawerArrowDrawable.java:64) at android.support.v7.app.ActionBarDrawerToggle$DrawerArrowDrawableToggle.(ActionBarDrawerToggle.java:469) at android.support.v7.app.ActionBarDrawerToggle.(ActionBarDrawerToggle.java:222) at android.support.v7.app.ActionBarDrawerToggle.(ActionBarDrawerToggle.java:150)` – AndreaF Oct 18 '14 at 13:24
  • You're using Eclipse right? Did you check the `android-support-v7-appcompat.jar` in your project properties --> Java Build Path --> Order and Export? Furthermore it may be helpful to move the v7-appcompat to the top. – reVerse Oct 18 '14 at 13:25
  • I use IntelliJ I have added the `android-support-v7-appcompat.jar` to the project dependencies in the same way of support-v4 (otherwise doesn-t even compile) – AndreaF Oct 18 '14 at 13:28
  • 1
    Mhkay unfortunately I'm not familiar with IntelliJ. In Android Studio you just need to add `compile "com.android.support:appcompat-v7:21.0.0"` to your `build.gradle` file and you're good to go. – reVerse Oct 18 '14 at 13:31
  • I have checked many times if the library dependency is correctly configured, there is some other reason that cause the issue, I have thought that the library maybe is corrupted but I have tried to download and add it again from SDK manager with no result – AndreaF Oct 18 '14 at 13:35
  • following the other answer I correctly configured the library but Drawer is not shown on Jelly Bean and previous versions http://stackoverflow.com/questions/26442135/replace-deprecated-android-support-v4-app-actionbardrawertoggle-with-support-v7 – AndreaF Oct 18 '14 at 16:43
  • In my case it does not crash, but toggle button doesn't appear at all anymore. – Marek Oct 21 '15 at 19:17
  • Works for me, but don't forget to add import android.support.v7.app.ActionBarDrawerToggle; – Whome Mar 16 '17 at 03:00
27

you must use import android.support.v7.app.ActionBarDrawerToggle;

and use the constructor

public CustomActionBarDrawerToggle(Activity mActivity,DrawerLayout mDrawerLayout)
{
    super(mActivity, mDrawerLayout, R.string.ns_menu_open, R.string.ns_menu_close);
}

and if the drawer toggle button becomes dark then you must use the supportActionBar provided in the support library.

You can implement supportActionbar from this link: http://developer.android.com/training/basics/actionbar/setting-up.html

Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
Abhi1227
  • 416
  • 4
  • 7
  • Thanks, a manual import of `import android.support.v7.app.ActionBarDrawerToggle;` worked for me. Even though I have auto-imports usually, that one did not auto-import. – Azurespot Jan 20 '15 at 05:33
  • And delete `import android.support.v4.app.ActionBarDrawerToggle;` – VikingGlen Nov 17 '15 at 05:16
8

Insted of

drawer.setDrawerListener(toggle);

You can use

drawer.addDrawerListener(toggle);
erluxman
  • 18,155
  • 20
  • 92
  • 126