Android Shape Drawables Tutorial

Image for post
Image for post

First, we will go over the advantages and disadvantages of the ShapeDrawables. Then we will create some Drawables that could be used in your app and lastly for the grand finale we will try to replicate a gradient as can be seen in the Spotify app/website.

Why should you use ShapeDrawables?

When you want to use PNG or JPEG images in your application, you have to provide multiple copies of the same image for different screen densities. That, of course, clutters your app with copies of the same image. Yes, sometimes that is the path we have to choose because we can’t use Drawables for every single case, but we can dramatically reduce our application’s size if we can use Drawables instead. ShapeDrawables are a series of commands that tell how to draw something on the screen. That is why they can be resized and stretched as much as we want, without losing any quality. We can recolor and manipulate them even when the app is running and use the same ShapeDrawable multiple times in our app. Since ShapeDrawables are a subclass of the Drawable abstract class, we can use them in methods where a Drawable is expected. Click for the documentation of the ShapeDrawable.

Are there any disadvantages?

Of course, just like I have mentioned before we can’t use them in every case. I have said before that ShapeDrawable class is a subclass of the Drawable abstract class. There are other subclasses as well and every one of them has its own use case. You can click here to check other Drawable types and figure out which one is right for your case. Another issue is that they took a bit longer to draw than a Bitmap since there is a lot of parsing and drawing going on behind the scenes. But I think that is not a huge problem if your Drawables are simple.

My opinion is that you should use Drawables (ShapeDrawables) wherever you can, because they are easy to modify and they don’t take much space.

Let’s start coding

First let’s take a look at a simple example and then we will recreate a gradient as can be seen in the Spotify app/website.

Create a simple gradient ShapeDrawable in XML

First create a new drawable resource file.

Right click on res/drawable > New > Drawable resource file > give your file a name > use shape as a root element > click Ok

Shape root element defines that this is a ShapeDrawable.

This is how the first example looks like:

Image for post
Image for post
shape_drawable_example_1.xml

This is the code for the first example:

Some useful attributes that you can use when defining a shape:

You can specify the type of a shape using android:shape XML attribute in the shape tag. If you don’t specify the shape, the default rectangle type is selected. Other available shapes are oval, line and ring. Here is an example:

android:shape= “oval”

Since our shape is a rectangle, we can round rectangle’s corners. You can do that inside of the corners tag. You can specify the radius for all of the corners using android:radius. Here is an example:

android:radius=”21dp” 

You can, of course, use the value from dimens resource file. If you want to be a bit more experimental, you can use a different radius for each corner. You can do that using android:topLeftRadius, android:topRightRadius, android:bottomLeftRadius and android:bottomRightRadius. Here is an example:

android:bottomLeftRadius=”10dp”

If you want to use a solid color, you should use a solid tag and then inside of that tag you can specify the color using android:color. Here is an example:

android:color=@color/your_color_name

All the gradient attributes have to be in a gradient tag. You can specify your start, center and end color using android:startColor, android:centerColor and android:endColor. Here is an example:

android:startColor=@color/your_color_name
android:centerColor=@color/your_color_name
android:endColor=@color/your_color_name

If you don’t specify the type of the gradient, the default linear is chosen. Other types are radial and sweep. Here is how to specify the gradient type:

android:type=”radial”

You can even change the angle of the gradient. For example, if you want your gradient to go from bottom left to top right, you have to set your angle to android:angle=”45” (note that the angle has to be a multiple of 45).

If you want, you can specify the size of the shape. Remember that you can change the size later, for example when you use the ShapeDrawable in a ImageView. You can change the size inside the size tag. android:layout_height and android:layout_width are used to do that. You probably know these two:

android:layout_height=”40dp”
android:layout_width=”10dp”

Sometimes you want an outline around your shape and to do that you can use the stroke tag. You can specify the width and color of the outline using android:width and android:color. Here is an example:

android:width=”2dp”
android:color=@color/your_beautiful_color

You can even have dashes as an outline around your shape. To get that effect you have to use these two attributes: android:dashGap, android:dashWidth. Here is an example:

android:dashGap=”1dp”
android:dashWidth=”4dp”

Other attributes that I haven’t mentioned can be found in the documentation here.

Let’s use our shape in a View

After you are happy with your shape, you can use it in a View, for example. This is how you could use a circle shape in an ImageView using XML.

<ImageView xmlns:android=”http://schemas.android.com/apk/res/android"
android:id=”@+id/my_image_view”
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:background=”@drawable/my_custom_circle”
android:text=”@string/hello_world” />

Instead of using android:background attribute, you can use:

android:src=”@drawable/my_custom_circle”

This is how you can do the same thing using Java

ImageView myImageView = (ImageView) findViewById(R.id.my_image_view);imageView.setImageResource(R.drawable.my_custom_circle);

Modify shapes using Java

Now you know how to define shapes using XML and how to use them in Views. But there has to be a way to define and modify them using Java as well, right? Sure, but I recommend defining shapes using XML, if you can, because it is much easier to visualize and check your progress. If you have used XML to define your shape, you can use getDrawable method in Java to get the reference to your shape. This method will return a Drawable. Note that you can manipulate your shapes even when your app is running.

Drawable drawable = getDrawable(R.drawable.button_shape);

Then you can cast your Drawable into a GradientDrawable, for example.

GradientDrawable gradientDrawable = (GradientDrawable) drawable;

At this point you are ready to start modifying your GradientDrawable. Here are a few examples:

gradientDrawable.setColor(ContextCompat.getColor(this, R.color.colorPrimary));
gradientDrawable.setShape(GradientDrawable.OVAL);
gradientDrawable.setStroke(12, Color.CYAN);

There are much more methods to try out and I want you to do that by clicking here.

Define shapes using Java

This is how you can create and use shapes only using Java. Link for more information about that.

RoundRectShape roundRectShape = new RoundRectShape(new float[]{
10, 10, 10, 10,
10, 10, 10, 10}, null, null);
ShapeDrawable shapeDrawable = new ShapeDrawable(roundRectShape);
shapeDrawable.getPaint().setColor(Color.parseColor(“#FFFFFF”));
ImageView myImageView = findViewById(R.id.my_image_view);
myImageView.setBackground(shapeDrawable);
// or you can use myImageView.setImageDrawable(shapeDrawable);

At this point you know how to create and use Drawables using Java and/or XML and what they are used for.

Now it is time for the last step. Let’s recreate this Spotify’s gradient using our new skills.

Image for post
Image for post
Original image
Image for post
Image for post
Our recreation

Now it is your turn. I have shown you just a simple example and I want you to start creating your own shapes and gradients.

Technology. Android. Guitar.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store