Drawing Custom Shapes in Android

Learn how to draw custom shapes and paths in Android by creating a neat curved profile card with gradient colors. By Ahmed Tarek.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Finalizing the Curve

You're almost finished creating the curve. In ProfileCardPainter, go to the last line in paint() and add the following code:

//1
val curvedShapeBounds = RectFFactory.fromLTRB(
    shapeBounds.left,
    shapeBounds.top + shapeBounds.height() * 0.35f,
    shapeBounds.right,
    shapeBounds.bottom
)
//2
drawCurvedShape(canvas, curvedShapeBounds, avatarBounds)

Here, you:

  1. Create a RectF that is similar to the shapeBounds rect, except you've shifted its top slightly to the bottom by 35% of the shapeBounds' height: This is the red dashed RectF in the image above.
  2. Call drawCurvedShape() and pass the canvas object, the curved shape bounds and the avatar bounds to it.

Build and run the app to see the neat background curve behind the avatar:

Add a curve behind the avatar

So you're done, right? Almost. There's still one more finishing touch you need to add.

Adding Gradient Paint

You've created your first beautiful, custom curved shape, but your graphic designer wants you to do one more thing: Add gradient colors to your curved shape.

There are different types of shaders or gradients, including linear gradients, which transition through at least two colors in a straight line, and radial gradients, which transition through colors starting from a central point and radiating outward.

Right now, you'll create a shader, a linear gradient described by three colors. Each color needs a stop to specify its position on a line from 0.0 to 1.0.

Start by creating a new function called createGradient() inside ProfileCardPainter with the following code:


private fun createGradient(bounds: RectF): LinearGradient {
  //1
  val colors = intArrayOf(color.darkerShade(), color, color.darkerShade())
  //2
  val stops = floatArrayOf(0.0f, 0.3f, 1.0f)
  //3
  return LinearGradient(
      bounds.centerLeft.x, bounds.centerLeft.y,
      bounds.centerRight.x, bounds.centerRight.y,
      colors,
      stops,
      Shader.TileMode.REPEAT
  )
}

Here's what's going on in this code:

  1. You create a list of three colors, where the middle color is the profile color and the first and last colors are darker shades of that profile color.
  2. Then you create a list of three stops. The first is 0.0, which puts the corresponding color in the colors list at the zero position of the gradient color. In the same way, the middle and the stops specify the positions of their corresponding colors in the color list.
  3. Finally, you create a linear gradient by passing the start coordinates and the end coordinates of the gradient with the given colors and stops, and the shader TileMode to repeat the gradient in case the area which you fill is larger than the shader you created.

Now go to drawCurvedShape() and update the paint object to use the new linear gradient instead of a solid color.

Replace this line:

paint.color = color.darkerShade()

With this one:

paint.shader = createGradient(bounds)

Here, you create a new gradient and set it to the paint object.

Finally, build and run the app to see a gradient within the background curve:

Background curve with gradient

Congratulations! You've created a beautiful profile card with an eye-catching custom background shape and shading.

Where to Go From Here?

You can download the completed final project using the Download Materials button at the top or bottom of the tutorial.

Wow, that was a lot of work! But you learned a lot, too. In addition to taking a deep look at Canvas and many Android Graphics APIs, you learned how to:

  • Prepare your custom shape on paper before coding.
  • Use Path and how to add different lines to it sequentially.
  • Draw a curved shape in gradient colors.

To learn more about Canvas and Android custom views check out the following links:

Also, you can check RichPath library. It's an open-source library that gives you full control over your custom shapes in vector drawable format so you can manipulate and animate them easily at runtime.

Feel free to share your feedback, comments or ask questions in the forum below. Don't stop drawing. ;]