Android's NavigationDrawer without AppCompat - android

I am trying to use the NavigationDrawer within an application that should support Android 4.+
Thus I am using native Activity, ActionBar and Fragment classes (not the support and AppCompat classes).
All seems well except that the navigation drawer icon (the kind-of burger) does not animate to the left when the drawer opens.
Does NavigationDrawer require me to use the AppCompat library and the corresponding support ActionBar stuff?

No, NavigationDrawer doesn't require you to user AppCompat staff. Check the listeners they are the most likely cause of your problem, or post your code for us to check.
I am not sure whether the link is correct, but in some of Google I/O 2013 Talk, they recommend to use support library even if you target API 14+ for the simple reason that bug fixes will be faster delivered to you with support library release then with framework release. For this reason I switched our application to use support library components.
P.S. I think it was in this talk http://www.youtube.com/watch?v=qlrKh-L4bqU

If you want to use the DrawerLayout for NavigationDrawer, you will have to use support library v4.
http://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html
or perhaps you forgot the ActionBarDrawerToggle
public void onCreate(Bundle savedInstanceState) {
...
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer icon to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */
) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
}
};
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
}
#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);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Pass the event to ActionBarDrawerToggle, if it returns
// true, then it has handled the app icon touch event
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle your other action bar items...
return super.onOptionsItemSelected(item);
}

Related

Android Studio - Navigation Drawer

I'm trying to make a simple app with Navigation Drawer with Android Studio.
Since Android Studio has this type of activity already implemented, i used it.
But now i'm unable to change the resource of image button in the top left of the ActionBar that opens the drawer.
Here's a part of my NavigationDrawerFragment.java :
public void setUp(int fragmentId, DrawerLayout drawerLayout) {
mFragmentContainerView = getActivity().findViewById(fragmentId);
mDrawerLayout = drawerLayout;
// set a custom shadow that overlays the main content when the drawer opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// set up the drawer's list view with items and click listener
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the navigation drawer and the action bar app icon.
mDrawerToggle = new ActionBarDrawerToggle(
getActivity(), /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.navigation_drawer_open, /* "open drawer" description for accessibility */
R.string.navigation_drawer_close /* "close drawer" description for accessibility */
) {
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
if (!isAdded()) {
return;
}
getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
if (!isAdded()) {
return;
}
if (!mUserLearnedDrawer) {
// The user manually opened the drawer; store this flag to prevent auto-showing
// the navigation drawer automatically in the future.
mUserLearnedDrawer = true;
SharedPreferences sp = PreferenceManager
.getDefaultSharedPreferences(getActivity());
sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
}
getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
};
// If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
// per the navigation drawer design guidelines.
if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
mDrawerLayout.openDrawer(mFragmentContainerView);
}
// Defer code dependent on restoration of previous instance state.
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
this image could help you to understand my problem
Thanks
Use this code
actionBar.setHomeAsUpIndicator(R.drawable.menuw_24);
I strongly suggest that you use the Design Support library, which provides a NavigationView to create a Material Design Navigation Drawer. Bottom line is that it is dead simple to create one. Don't struggle with the template.
This should get you started.

How do you replace the default navdrawer icon in android?

I want to change the default DrawerLayout icon on the upper left side to my own image but I don't know why it does not work on load of app. The icon only changes when I have opened or closed the side menu. I also want to disable the animation, it is disabled after I changed the icon but that only happens after it is opened and closed. I don't know why this does not work on load of the activity
actionBar = (Toolbar) findViewById(R.id.custom_screen_toolbar);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
drawerLayout, actionBar, R.string.drawer_open, R.string.drawer_close) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
actionBar.setTitle("Nav Menu Close");
actionBar.setNavigationIcon(R.drawable.action_bar_menu);
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
actionBar.setTitle("Nav Menu Open");
actionBar.setNavigationIcon(R.drawable.action_bar_back_icon);
}
};
// Set the drawer toggle as the DrawerListener
drawerLayout.setDrawerListener(drawerToggle);
actionBar.setSubtitleTextColor(getResources().getColor(
R.color.light_gray));
actionBar.setBackgroundResource(R.drawable.divider_action_bar);
actionBar.setNavigationIcon(R.drawable.action_bar_menu);
setSupportActionBar(actionBar);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
I believe calling setDisplayHomeAsUpEnabled(true) will cause the navigation icon to be set to the back arrow icon, in addition to providing the default behavior of finishing the activity when it's selected.
You should be able to remove that line and setHomeButtonEnabled(true) to get the effect you want.

android - open navigation drawer by clicking the app icon?

I use a navigation drawer in my app (the type of navigation that you open by sliding from the left side of the screen). Now, usually you can also open it by tapping the app icon, and when I looked it up, I found a whole bunch of code to add to your activity. And just for a simple button. I suppose thats not exactly what I am looking for? And if it really needs to be so much code for a single button, what is the best way to make the code more clear? Thank you, and sorry for being such an android newb.
I ran into this issue also, assuming you already have an ActionBarDrawerToggle as #Kernald suggested, you need to add the following also to your Activity:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Pass the event to ActionBarDrawerToggle, if it returns
// true, then it has handled the app icon touch event
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle your other action bar items...
return super.onOptionsItemSelected(item);
}
This let's the toggle handle the icon button press on the ActionBar, causing the Drawer to slide out.
Everything you need is described in the Navigation Drawer Guide from Google. Basically, you need to enable the "up" action on the ActionBar:
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
Then you need to bind it to a Toggle:
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer icon to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */
) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
}
};
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);

How to add "menu" indicator next to Action Bar's app icon?

At least Gmail and Youtube Android apps use a side menu (navigation drawer?) that opens by swiping, or by clicking the app icon (home button):
Is the menu indicator / icon in the screenshot above a ready-made part of Android SDK? (Or a custom icon Google uses in their apps?) In any case, what's the easiest way to get your home button to look like that, i.e., like it opens a menu?
(targetSdkVersion 18; minSdkVersion 14)
Resolution
Finally got it working. What was missing for me was 1) the actual icon and 2) deferred call to syncState() on the ActionBarDrawerToggle.
To create similar implementation / look in your application you should use ActionBarDrawerToggle and set your custom icon as indicator next to ActionBar home button. For example :
import android.app.ActionBar;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
private void setUpDrawerToggle(){
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the navigation drawer and the action bar app icon.
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.navigation_drawer_open, /* "open drawer" description for accessibility */
R.string.navigation_drawer_close /* "close drawer" description for accessibility */
) {
#Override
public void onDrawerClosed(View drawerView) {
invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
#Override
public void onDrawerOpened(View drawerView) {
invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
};
// Defer code dependent on restoration of previous instance state.
// NB: required for the drawer indicator to show up!
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
Where R.drawable.ic_drawer is actually the icon to use as indicator. You can find it in Android Asset Studio; see Navigation Drawer Indicator.
References
ActionBarDrawerToggle
Creating a Navigation Drawer
Android-Developer and HpTerm helped me in the right rirection, by
Pointing out this is indeed NavigationDrawer specific (which I was already using as in Google's example)
Telling where to find the ic_drawer.png icon (→ Android Asset Studio)
Now, unfortunately, creating ActionBarDrawerToggle like below seems not to be enough.
At least on my Nexus 7 (API 18) test device.
drawerToggle = new ActionBarDrawerToggle(this,
drawerLayout,
R.drawable.ic_navigation_drawer,
R.string.side_menu_open,
R.string.side_menu_closed) {
// ...
};
Partial solution (API level 18+)
I found one way to make the indicator show up though: setHomeAsUpIndicator(). The downside: that method was added in API level 18.
#Override
protected void onCreate(Bundle savedInstanceState) {
// ...
getActionBar().setDisplayHomeAsUpEnabled(true); // also required
if (Build.VERSION.SDK_INT >= 18) {
getActionBar().setHomeAsUpIndicator(
getResources().getDrawable(R.drawable.ic_navigation_drawer));
}
}
So now the question remains: how to make this work (in my case) for API levels 14 through 17?
I verified on a 4.1.2 (API 16) device that the ic_drawer icon does not show up. With setDisplayHomeAsUpEnabled(true) I get the normal "home" icon (small arrow pointing left) and without it, the space left to my app icon remains blank.
Final solution
Got it working using the edited version of Android-Developer's answer.
Quite curiously, what was missing from my ActionBarDrawerToggle initialisation code was this:
// Defer code dependent on restoration of previous instance state.
drawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
With that included, calling setHomeAsUpIndicator() is not needed.
The keyword here is NavigationDrawer; there's a full working code example on the Android developer site.
READ THE END OF THE LINK GIVEN : Open and Close with the App Icon
The following code is copied from there
public class MainActivity extends Activity {
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
...
public void onCreate(Bundle savedInstanceState) {
...
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer icon to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */
) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
}
};
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
}
#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);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Pass the event to ActionBarDrawerToggle, if it returns
// true, then it has handled the app icon touch event
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle your other action bar items...
return super.onOptionsItemSelected(item);
}
...
}
Some files are available as download and the small 3 lines with the animation effect is fully exemplified.
You have to copy thoses files in the corresponding drawable folder. Depending on the theme you use, dark or light you have a different set of icons.
In my case I simply copied the drawer_shadow.9.png and ic_drawer.png in the drawable folder and followed the example and everything works just fine.
The icons are available in the link I provided, but they are NOT in the "Action Bar Icon Pack", they are in the sample app in the corresponding res/drawable folders.

Toggle DrawerLayout With Title Only (NO App Icon)?

I have an activity with a DrawerLayout. I can open the drawer two different ways...by swiping from the left area of the screen towards the right and by clicking the app title. I DO NOT have an app icon displayed, only a title. I've implemented this exactly as recommended by Google here: Creating a Navigation Drawer: Open and Close with the App Icon
Everything is functional as far as opening and closing the drawer itself. However, it does not display the standard DrawerLayout icon that is suppose to be used. Instead I get the regular up caret (looks like a less than sign).
As soon as I add the app icon back to the ActionBar it begins to work as expected. The Drawer layout icon displays and animates when the drawer is opened or closed. I've tried removing the app icon both in my styles XML file and programmatically.
Is there a way to get the DrawerLayout icon working WITHOUT the app icon???
UPDATE: I've found a work around, but it's a hack more so than a solution. I simply created a 1x1 pixel transparent PNG (blank.png) and set it as my app icon in my styles.xml file. Below is all relative code:
styles.xml
<style name="MyCustomTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:actionBarStyle">#style/MyCustomActionBar</item>
<item name="android:icon">#drawable/blank</item>
</style>
<style name="MyCustomActionBar" parent="#android:style/Widget.Holo.ActionBar">
<item name="android:displayOptions">showHome|showTitle|homeAsUp</item>
</style>
MainActivity -> onCreate()
this.navDrawerToggle = new ActionBarDrawerToggle
(
this,
this.navDrawerLayout,
R.drawable.icon_nav_drawer,
R.string.nav_drawer_open,
R.string.nav_drawer_closed
)
{
public void onDrawerClosed(View view) {}
public void onDrawerOpened(View drawerView) {}
};
MainActivity -> onPostCreate()
super.onPostCreate(savedInstanceState);
this.navDrawerToggle.syncState();
MainActivity -> onResume()
this.navDrawer.setOnItemClickListener(new DrawerItemClickListener());
this.navDrawerLayout.setDrawerListener(this.navDrawerToggle);
MainActivity -> onPause()
this.navDrawer.setOnItemClickListener(null);
this.navDrawerLayout.setDrawerListener(null);
MainActivity -> onConfigurationChanged(Configuration newConfig)
super.onConfigurationChanged(newConfig);
navDrawerToggle.onConfigurationChanged(newConfig);
MainActivity -> onOptionsItemSelected(MenuItem item)
if (this.navDrawerToggle.onOptionsItemSelected(item)) {return true;}
else
{
// A bunch of item click handling happens here...
return true;
}
I was curious about this so I tried it with the sample for the DrawerLayout and it worked fine. Also, it seems like you have to use your own drawer icon drawable, it's recommended anyways. You can download the default assets from this site Creating a Navigation Drawer and put them in their respective drawable resource folder.
Here's what worked for me:
ActionBar actionBar = getActionBar();
// Let's get rid of the app icon here
actionBar.setIcon(null);
actionBar.setTitle("App Name");
// Setting these 3 options allows us to show the title as well as a "Home" elements
// "Home" elements include the Up and/or Drawer icon. The DISPLAY_HOME_AS_UP will enable
// and show the Drawer icon, we'll be "replacing" the "up" button with the drawer icon below
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE
| ActionBar.DISPLAY_SHOW_HOME
| ActionBar.DISPLAY_HOME_AS_UP);
// Get a reference of the DrawerLayout
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerLayout.setDrawerListener(drawerToggle);
// Setting ActionBarDrawerToggle will allow you to set the drawables for the drawer
// (this will also give you the nice/smooth animation) as well as allow you to do some
// other things depending on the events: onDrawerClosed & onDrawerOpened.
ActionBarDrawerToggle drawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
drawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_closed /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view) {
actionBar.setTitle("Closed...");
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
actionBar.setTitle("Open...");
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
// Set a listener to be notified of drawer events.
drawerLayout.setDrawerListener(drawerToggle);
UPDATE: It seems like the android:displayOptions on the ActionBar style are not being accounted for. Use actionBar.setDisplayOptions(int options) instead.
getActionBar().setIcon(android.R.color.transparent);
This worked for me..... ;)
After setting the drawer toggle you need to call the following method:
mDrawerToggle.syncState();
so your code would look like this:
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view) {
actionBar.setTitle(mTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
actionBar.setTitle("Preview Mode");
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerToggle.syncState();
mDrawerLayout.setDrawerListener(mDrawerToggle);

Categories

Resources