When using the drawer layout is there a way to overlay the drawer view over the action bar? I do not want to hide the action bar when the drawer is shown. I want the action bar to simply stay put, but be sent to the background. An example of this is the iOS Play Music app...
My current implementation hides and shows the action bar when the drawer state changes, but I do not like this user experience.
public void onDrawerClosed(View view) {
getActionBar().show();
invalidateOptionsMenu();
}
public void onDrawerOpened(View drawerView) {
getActionBar().hide();
invalidateOptionsMenu();
}
To use a DrawerLayout, position your primary content view as the first child with width and height of match_parent and no layout_gravity> . Add drawers as child views after the main content view and set the layout_gravity appropriately. Drawers commonly use match_parent for height with a fixed width.
Drawer Layout is the root layout in which we define a FrameLayout and a Navigation View. In Navigation View we set the items from menu file and FrameLayout is used to replace the Fragments on the click of menu items.
In Android applications, ActionBar is the element present at the top of the activity screen. It is a salient feature of a mobile application that has a consistent presence over all its activities. It provides a visual structure to the app and contains some of the frequently used elements for the users.
I searched the web in order to find any good solution for this problem and haven't found. So I did a trick that did this.
First of all we need to request action bar overlay feature. So in onCreate()
of your activity, before setContntView()
call: requestWindowFeature(com.actionbarsherlock.view.Window.FEATURE_ACTION_BAR_OVERLAY);
It will make everything including navigation drawer draw behind action bar. We don't need this, so we need to set the top margin of our FrameLayout which hosts our fragments in the activity with the exact height of the action bar. In the layout file of the activity we need to do the following:
<!-- Framelayout to display Fragments -->
<FrameLayout
android:id="@+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize" />
It will make only navigation drawer appear behind the action bar. Now we will hide the action bar when the navigation drawer is opened on half, and will show it when the drawer is nearly closed. To do this we need to make the following in the activity:
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
if(slideOffset > 0.5){
actionBar.setBackgroundDrawable(null);
actionBar.hide();
} else {
actionBar.show();
if(slideOffset < 0.1){
actionBar.setBackgroundDrawable(layerDrawable);
}
}
}
As you can see I also change the background drawable of the action bar to make it transparent when before I begin to hide it, and change it back with my custom background when I show it back.
My custom background is a layerListDrawable which is all transparent but have a divider in bottom with some shadow.
And to achieve this I have defined the following layer-list in XML:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="0dp" android:left="0dp" android:bottom="0dp" android:right="0dp">
<shape android:shape="rectangle">
<solid android:color="@android:color/transparent"/>
</shape>
</item>
<item android:top="0dp" android:left="0dp" android:bottom="0dp" android:right="0dp">
<shape android:shape="rectangle">
<solid android:color="#afafaf"/>
</shape>
</item>
<item android:top="0dp" android:left="0dp" android:bottom="0dp" android:right="0dp">
<shape android:shape="rectangle">
<gradient
android:angle="270"
android:startColor="#88afafaf"
android:endColor="#33afafaf"
/>
</shape>
</item>
</layer-list>
And to get the background I need from this XML I do the following in the activity:
final ActionBar actionBar = getSupportActionBar();
final LayerDrawable layerDrawable = (LayerDrawable) getResources()
.getDrawable(R.drawable.shadow_divider);
final TypedArray styledAttributes = getTheme().obtainStyledAttributes(
new int[] { R.attr.actionBarSize });
int topOffset = (int) (styledAttributes.getDimension(0, 0));
styledAttributes.recycle();
layerDrawable.setLayerInset(1, 0, topOffset - 3, 0, 2);
layerDrawable.setLayerInset(2, 0, topOffset - 2, 0, 0);
actionBar.setBackgroundDrawable(layerDrawable);
where R.drawable.shadow_divider is the XML layer-list I have defined earlier.
It looks really great! Hope it can help someone.
EDIT
I had a small bug here which can be a reason of a crush sometimes. Here is the fixed code: `
<FrameLayout
android:id="@+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
**android:paddingTop="?attr/actionBarSize"** />`
It should be paddingTop not layout_marginTop!
That's the proper effect in Android defaults. If you want to emulate the iOS effect, you'll probably have to do it yourself, because AFAIK the drawer component of the support library doesn't allow such type of configurations.
Anyway, every time a programmer codes a lot just to emulate some fancy (and much probably not worthy) iOS effect in Android, a little cat dies...
I don't think you'll be able to do this with Android's provided Navigation Drawer (without doing something really hacky), since doing this really goes against Android design patterns. If you want a library that does what you're looking for, I've used this library before Android came out with it's own widget, and it does what you're looking for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With