Gradients are a trend in mobile app design that brings life to the app UI. Creating a gradient toolbar is a relatively simple task in Android, you achieve it by simply adding a gradient background to the toolbar, but this doesn’t cover the status bar, thus not creating the desired effect.

Toolbar and status bar are separate entities in Android. Thus there is no straightforward way to have a single gradient from the top of the screen to the bottom edge of our toolbar. But there are hacks to achieve this. Let’s see how we can do it.

The first step is to create a gradient drawable. Create an XML file in your drawable folder named gradient_bg.xml.

<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient android:angle="0"
        android:startColor="#2ECAD5"
        android:endColor="#2B95CE"/>

</shape>

For choosing awesome gradient colors for your app, I recommend CoolHue and uiGradients.

Now, before we design our custom toolbar, we need to make sure that Android doesn’t attach a toolbar automatically. Open your styles [res/values/styles.xml file]. There are two ways to do this.

1. Use a style that doesn’t contain any ActionBar, like this one.

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

2. Or alternatively, override the style

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
</style>

Okay! Now it’s time to create our custom toolbar. 24dp is the default height of the status bar. And the default height of status bar + toolbar is 80dp. So we give our RelativeLayout a height of 80dp to accommodate both, and we keep a top margin of 24dp because in the next steps we are about to push the parent container out of its default area into the entire screen area that includes the status bar.

In your activity layout, add the following code at the top of the root layout.

<RelativeLayout
    android:layout_alignParentTop="true"
    android:id="@+id/appbarlayout"
    android:elevation="4dp"
    android:background="@drawable/gradient_bg"
    android:layout_width="match_parent"
    android:layout_height="80dp">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_marginTop="24dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</RelativeLayout>

And in your activity’s onCreate method, add the following:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    //this comes before setContentView(...)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        Window window = getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
    }
    
    //set content view here
}

There’s a catch here. When we add FLAG_LAYOUT_NO_LIMITS, it makes our container layout cover the entire screen, including the soft navigation buttons that might be on some Android screens.

To avoid the soft navigation buttons from overlapping on your layout, we need to get their height; and add a padding of this height to our container layout.

Add this function in your activity, or better add it to your Helper class if you plan to use this gradient layout in all your activities.

public static int getSoftButtonsBarSizePort(Activity activity) {
    // getRealMetrics is only available with API 17 and +
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        DisplayMetrics metrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
        int usableHeight = metrics.heightPixels;
        activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
        int realHeight = metrics.heightPixels;
        if (realHeight > usableHeight)
            return realHeight - usableHeight;
        else
            return 0;
    }
    return 0;
}

Now, we use this and add bottom padding to our container layout.

Add the following line after setContentView(…). Use the ID of the root layout in the activity layout XML. For example, if your root layout is a RelativeLayout with ID as “container”, this is the code.

((RelativeLayout) findViewById(R.id.container)).setPadding(0,0,0,getSoftButtonsBarSizePort(this));

That’s it! Run the app, you should see a smooth gradient effect. You can play with the gradient colors and the angle.


UPDATE: NEW METHOD for minSdkVersion 21+

Create your gradient shape file.

Create an XML file in your drawable folder named gradient_bg.xml.

<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <gradient android:angle="0"
        android:startColor="#2ECAD5"
        android:endColor="#2B95CE"/>

</shape>

For choosing awesome gradient colors for your app, I recommend CoolHue and uiGradients.

Override your app style. The first two styles here, remove the default action bar of android from your app so that you can add your custom-designed action bar. The next two lines ensure that your app window covers the status bar on the top, but leaves the soft button bar on the bottom.

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowDrawsSystemBarBackgrounds">false</item>
</style>

Okay! Now it’s time to create our custom toolbar. 24dp is the default height of the status bar. And the default height of status bar + toolbar is 80dp. So we give our RelativeLayout a height of 80dp to accommodate both, and we keep a top margin of 24dp because in the next steps we are about to push the parent container out of its default area into the entire screen area that includes the status bar.

In your activity layout, add the following code at the top of the root layout.

<RelativeLayout
    android:layout_alignParentTop="true"
    android:id="@+id/appbarlayout"
    android:elevation="4dp"
    android:background="@drawable/gradient_bg"
    android:layout_width="match_parent"
    android:layout_height="80dp">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_marginTop="24dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</RelativeLayout>

And in your activity’s onCreate method, add the following:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    //this comes before setContentView(...)
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS );
    
    //set content view here
}

That’s it! Run the app, you should see a smooth gradient effect. You can play with the gradient colors and the angle.