Have you noticed how some android applications move the content inward when you open the navigation drawer? Isn’t that a cool effect! In this tutorial I am going to show you exactly how you can achieve the same. Below is the effect that we are going to create in this tutorial.

Setting up the layout

You must know the basics of DrawerLayout, having said that, below is the layout file that we will pay with.

Navigation Drawer layout file <?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawerLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorAccent" tools:context="com.example.gurleensethi.playground.DrawerContentSlideActivity"> <LinearLayout android:id="@+id/content" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorPrimary" android:gravity="center_horizontal" android:orientation="vertical" android:padding="16dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Sliding Drawer Tutorial" android:textColor="@android:color/white" android:textSize="24sp" /> </LinearLayout> <LinearLayout android:id="@+id/drawer" android:layout_width="200dp" android:layout_height="match_parent" android:layout_gravity="start" android:background="@color/colorAccent" android:gravity="center_horizontal" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="80dp" android:text="You are in the drawer" android:textColor="@android:color/white" /> <View android:layout_width="match_parent" android:layout_height="2dp" android:layout_marginTop="40dp" android:background="@android:color/white" android:visibility="gone" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="Option 1" android:textColor="@android:color/white" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="Option 2" android:textColor="@android:color/white" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="Option 3" android:textColor="@android:color/white" android:textSize="20sp" /> </LinearLayout> </android.support.v4.widget.DrawerLayout> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 <? xml version = "1.0" encoding = "utf-8" ?> < android . support . v4 . widget . DrawerLayout xmlns : android = "http://schemas.android.com/apk/res/android" xmlns : app = "http://schemas.android.com/apk/res-auto" xmlns : tools = "http://schemas.android.com/tools" android : id = "@+id/drawerLayout" android : layout_width = "match_parent" android : layout_height = "match_parent" android : background = "@color/colorAccent" tools : context = "com.example.gurleensethi.playground.DrawerContentSlideActivity" > < LinearLayout android : id = "@+id/content" android : layout_width = "match_parent" android : layout_height = "match_parent" android : background = "@color/colorPrimary" android : gravity = "center_horizontal" android : orientation = "vertical" android : padding = "16dp" > < TextView android : layout_width = "wrap_content" android : layout_height = "wrap_content" android : text = "Sliding Drawer Tutorial" android : textColor = "@android:color/white" android : textSize = "24sp" / > < / LinearLayout > < LinearLayout android : id = "@+id/drawer" android : layout_width = "200dp" android : layout_height = "match_parent" android : layout_gravity = "start" android : background = "@color/colorAccent" android : gravity = "center_horizontal" android : orientation = "vertical" > < TextView android : layout_width = "wrap_content" android : layout_height = "wrap_content" android : layout_marginTop = "80dp" android : text = "You are in the drawer" android : textColor = "@android:color/white" / > < View android : layout_width = "match_parent" android : layout_height = "2dp" android : layout_marginTop = "40dp" android : background = "@android:color/white" android : visibility = "gone" / > < TextView android : layout_width = "wrap_content" android : layout_height = "wrap_content" android : layout_marginTop = "16dp" android : text = "Option 1" android : textColor = "@android:color/white" android : textSize = "20sp" / > < TextView android : layout_width = "wrap_content" android : layout_height = "wrap_content" android : layout_marginTop = "16dp" android : text = "Option 2" android : textColor = "@android:color/white" android : textSize = "20sp" / > < TextView android : layout_width = "wrap_content" android : layout_height = "wrap_content" android : layout_marginTop = "16dp" android : text = "Option 3" android : textColor = "@android:color/white" android : textSize = "20sp" / > < / LinearLayout > < / android . support . v4 . widget . DrawerLayout >

By default the effect when navigation drawer is opened/closed looks like this.

(I have kept the drawer size small, 200dp, you can set the size equal to whatever you want).

Everything we do from here on is going to be in our JAVA file. So lets get a reference to our views.

Reference the views in Activity final DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout); final LinearLayout content = (LinearLayout) findViewById(R.id.content); 1 2 final DrawerLayout drawerLayout = ( DrawerLayout ) findViewById ( R . id . drawerLayout ) ; final LinearLayout content = ( LinearLayout ) findViewById ( R . id . content ) ;

Removing the Scrim

Do you notice, when we open the drawer, the screen on the right side goes dark, this is called scrim, we don’t want this, so lets remove it. In your java file add the following line.

Remove drawer scrim drawerLayout.setScrimColor(Color.TRANSPARENT); 1 drawerLayout . setScrimColor ( Color . TRANSPARENT ) ;

By doing this we have removed the scrim colour. If you want to keep the scrim colour or change it to something else, its totally on you.

Moving the content!

Now we will move the content towards the positive x-axis whenever the drawer starts moving out. For that we will use the onDrawerSlide function provided by ActionBarDrawerToggle . Create an instance of ActionBarDrawerToggle , and override the onDrawerSlide function.

ActionBarDrawerToggle public class DrawerContentSlideActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { final DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout); final LinearLayout content = (LinearLayout) findViewById(R.id.content); drawerLayout.setScrimColor(Color.TRANSPARENT); ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.open, R.string.close) { @Override public void onDrawerSlide(View drawerView, float slideOffset) { super.onDrawerSlide(drawerView, slideOffset); } }; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class DrawerContentSlideActivity extends AppCompatActivity { @ Override protected void onCreate ( Bundle savedInstanceState ) { final DrawerLayout drawerLayout = ( DrawerLayout ) findViewById ( R . id . drawerLayout ) ; final LinearLayout content = ( LinearLayout ) findViewById ( R . id . content ) ; drawerLayout . setScrimColor ( Color . TRANSPARENT ) ; ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle ( this , drawerLayout , R . string . open , R . string . close ) { @ Override public void onDrawerSlide ( View drawerView , float slideOffset ) { super . onDrawerSlide ( drawerView , slideOffset ) ; } } ; } }

onDrawerSlide : When ever you start opening the drawer this function is called with arguments drawerView and slideOffset . drawerView is the content of the drawer you defined in the xml file( android:id="@+id/drawer ). slideOffset is a float value that changes when you open or close the drawer, it goes from 0 to 1 as you open the drawer and from 1 to 0 as you close it. So a value equal to 0 means the drawer is completely closed, value equal to 1 means the drawer is completely opened and value equal to 0.5 means drawer is in mid way of opening/closing.

So to slide the content towards right when drawer opens and vice versa, just add the following two lines of code in the onDrawerSlide function.

Also attach the actionBarDrawerToggle to the drawer by passing it in addDrawerListener() .

public class DrawerContentSlideActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { final DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout); final LinearLayout content = (LinearLayout) findViewById(R.id.content); drawerLayout.setScrimColor(Color.TRANSPARENT); ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.open, R.string.close) { @Override public void onDrawerSlide(View drawerView, float slideOffset) { super.onDrawerSlide(drawerView, slideOffset); float slideX = drawerView.getWidth() * slideOffset; content.setTranslationX(slideX); } }; drawerLayout.addDrawerListener(actionBarDrawerToggle); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class DrawerContentSlideActivity extends AppCompatActivity { @ Override protected void onCreate ( Bundle savedInstanceState ) { final DrawerLayout drawerLayout = ( DrawerLayout ) findViewById ( R . id . drawerLayout ) ; final LinearLayout content = ( LinearLayout ) findViewById ( R . id . content ) ; drawerLayout . setScrimColor ( Color . TRANSPARENT ) ; ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle ( this , drawerLayout , R . string . open , R . string . close ) { @ Override public void onDrawerSlide ( View drawerView , float slideOffset ) { super . onDrawerSlide ( drawerView , slideOffset ) ; float slideX = drawerView . getWidth ( ) * slideOffset ; content . setTranslationX ( slideX ) ; } } ; drawerLayout . addDrawerListener ( actionBarDrawerToggle ) ; } }

By doing this we get the following effect, finally the content moved!

The logic used is simple, as the drawer opens, we move the content using setTranslationX() function along the x-axis. We calculate the value that we have to move by multiplying the width of the drawer with the slideOffset .

Scaling the content

The final step is scale the content to get the desired effect. As the drawer opens we will scale down the content along x-axis and y-axis, and scale back up as the drawer closes. We know that the value of slideOffset goes from 0 to 1 as we open the drawer, we need to scale the content downwards as we open the drawer, so will subtract the value of slideOffset from 1.

Add the following lines to scale the content.

public class DrawerContentSlideActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { final DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout); final LinearLayout content = (LinearLayout) findViewById(R.id.content); drawerLayout.setScrimColor(Color.TRANSPARENT); ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.open, R.string.close) { @Override public void onDrawerSlide(View drawerView, float slideOffset) { super.onDrawerSlide(drawerView, slideOffset); float slideX = drawerView.getWidth() * slideOffset; content.setTranslationX(slideX); content.setScaleX(1 - slideOffset); content.setScaleY(1 - slideOffset); } }; drawerLayout.addDrawerListener(actionBarDrawerToggle); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class DrawerContentSlideActivity extends AppCompatActivity { @ Override protected void onCreate ( Bundle savedInstanceState ) { final DrawerLayout drawerLayout = ( DrawerLayout ) findViewById ( R . id . drawerLayout ) ; final LinearLayout content = ( LinearLayout ) findViewById ( R . id . content ) ; drawerLayout . setScrimColor ( Color . TRANSPARENT ) ; ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle ( this , drawerLayout , R . string . open , R . string . close ) { @ Override public void onDrawerSlide ( View drawerView , float slideOffset ) { super . onDrawerSlide ( drawerView , slideOffset ) ; float slideX = drawerView . getWidth ( ) * slideOffset ; content . setTranslationX ( slideX ) ; content . setScaleX ( 1 - slideOffset ) ; content . setScaleY ( 1 - slideOffset ) ; } } ; drawerLayout . addDrawerListener ( actionBarDrawerToggle ) ; } }

This is how its looks after scaling the content.

Whops!! Our content is completely disappearing when we open the drawer, although this effect is cool, it is not what we are looking for. The reason why this is happening is because our value of 1 - slideOffset goes from 1 to directly 0. We want it to start from 1 but not go to 0. The solution is to divide the slideOffset by a value which decreases it, so the final value inside the scale functions doesn’t evaluate to 0.

We will divide slideOffset by 6 (I found this optimal value by hit and trial). Update the code as follows.

public class DrawerContentSlideActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { final DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout); final LinearLayout content = (LinearLayout) findViewById(R.id.content); drawerLayout.setScrimColor(Color.TRANSPARENT); ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.open, R.string.close) { private float scaleFactor = 6f; @Override public void onDrawerSlide(View drawerView, float slideOffset) { super.onDrawerSlide(drawerView, slideOffset); float slideX = drawerView.getWidth() * slideOffset; content.setTranslationX(slideX); content.setScaleX(1 - (slideOffset / scaleFactor)); content.setScaleY(1 - (slideOffset / scaleFactor)); } }; drawerLayout.addDrawerListener(actionBarDrawerToggle); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public class DrawerContentSlideActivity extends AppCompatActivity { @ Override protected void onCreate ( Bundle savedInstanceState ) { final DrawerLayout drawerLayout = ( DrawerLayout ) findViewById ( R . id . drawerLayout ) ; final LinearLayout content = ( LinearLayout ) findViewById ( R . id . content ) ; drawerLayout . setScrimColor ( Color . TRANSPARENT ) ; ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle ( this , drawerLayout , R . string . open , R . string . close ) { private float scaleFactor = 6f ; @ Override public void onDrawerSlide ( View drawerView , float slideOffset ) { super . onDrawerSlide ( drawerView , slideOffset ) ; float slideX = drawerView . getWidth ( ) * slideOffset ; content . setTranslationX ( slideX ) ; content . setScaleX ( 1 - ( slideOffset / scaleFactor ) ) ; content . setScaleY ( 1 - ( slideOffset / scaleFactor ) ) ; } } ; drawerLayout . addDrawerListener ( actionBarDrawerToggle ) ; } }

By doing this we have achieved our desired effect. Yippee!

Play around with the value of scaleFactor , use different values for both X and Y scaling/translation to create different effects.

Sometimes the drawer comes with a shadow, which can be removed by adding the following line.

drawerLayout.setDrawerElevation(0f); 1 drawerLayout . setDrawerElevation ( 0f ) ;

Complete Code:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_drawer_content_slide); final DrawerLayout drawerLayout = findViewById(R.id.drawerLayout); final LinearLayout content = findViewById(R.id.content); ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.open, R.string.close) { private float scaleFactor = 6f; @Override public void onDrawerSlide(View drawerView, float slideOffset) { super.onDrawerSlide(drawerView, slideOffset); float slideX = drawerView.getWidth() * slideOffset; content.setTranslationX(slideX); content.setScaleX(1 - (slideOffset / scaleFactor)); content.setScaleY(1 - (slideOffset / scaleFactor)); } }; drawerLayout.setScrimColor(Color.TRANSPARENT); drawerLayout.setDrawerElevation(0f); drawerLayout.addDrawerListener(actionBarDrawerToggle); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @ Override protected void onCreate ( Bundle savedInstanceState ) { super . onCreate ( savedInstanceState ) ; setContentView ( R . layout . activity_drawer_content_slide ) ; final DrawerLayout drawerLayout = findViewById ( R . id . drawerLayout ) ; final LinearLayout content = findViewById ( R . id . content ) ; ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle ( this , drawerLayout , R . string . open , R . string . close ) { private float scaleFactor = 6f ; @ Override public void onDrawerSlide ( View drawerView , float slideOffset ) { super . onDrawerSlide ( drawerView , slideOffset ) ; float slideX = drawerView . getWidth ( ) * slideOffset ; content . setTranslationX ( slideX ) ; content . setScaleX ( 1 - ( slideOffset / scaleFactor ) ) ; content . setScaleY ( 1 - ( slideOffset / scaleFactor ) ) ; } } ; drawerLayout . setScrimColor ( Color . TRANSPARENT ) ; drawerLayout . setDrawerElevation ( 0f ) ; drawerLayout . addDrawerListener ( actionBarDrawerToggle ) ; }

That is it for this tutorial, here are some other articles that you might be interested in.

How to add Bottom Sheet in Android

Making a moving gradient background in Android

How to hide Floating Action Button when scrolling in Recycler View

Scanning and generating barcode in Android