How I drew custom shapes in bottom bar

Nour El Islam SAIDI
ProAndroidDev
Published in
5 min readNov 5, 2018

--

Recently, I received a design that contains BottomNavigationView. Until here everything is fine, but when I looked at the sketch I said ummm… it’s going to be hard 😟. Here is a copy of the real design:

Curve BottomNavigationView

I’ve never did something like this before, so I started looking online on how to create a curve custom view. After some research and a discussion with my colleagues, I found out that it’s a kind of Bézier curve.

Bézier curve

If you’ve used a design or a drawing software, you’ve probably used Bézier curves without even knowing. This is named after a French engineer, Pierre Bézier, who invented this method to describe the smooth curves needed when designing cars.

Bézier path in Adobe Illustrator (Wikipedia)

I then found a very good article that explains the type of curve I need, I strongly recommend reading it. In addition, it contains a tool to play with curves.

The type of curve that fits my design was Cubic Bézier curves and I’ll take the definition found in the article.

Cubic Bézier curves

Cubic Bézier curves are defined in terms of four control points. While the first and last control points specify locations of the endpoints of the drawn curve, the second and third control point influence the tangency of the curve.

Let’s now dive into the code and see how to create a cubic Bézier curve in Android.

First of all, we create a custom view that extends BottomNavigationView to take advantage of all its features and just focus on the design.

If we look at the code, we’ve only added an init()method, which will just initialize the path and paint objects.

The role of the path is to let us draw geometric forms including Bézier curve. The way path draws a line between two points : a start point and an end point. By default BottomNavigationView is in the form of a rectangle, so we’re going to use Path to redraw it with curves as shows the view above.

While path object has the role to control the styling and color of what is drawn. You can create an object just without passing a parameter, but it is possible to be more precise by specifying flags. The first thing is to determine what you want to draw, the contours of a view without its interior, or only the interior, or maybe both? In order to assign a value, we use setStyle(Paint.Style style) , For our case we will draw both contours and the interior so we’re going to use FILL_AND_STROKE.

We can then assign a color, you choose the color you like, and you set background color of the view to transparent to avoid default color in background.

Positions of points

First of all, we’ll initialize the positions of our points. The position of points depends on the width and height of the view. P1 is the beginning point of our path this is where we will start drawing. P2 is the start of our first curve. To calculate the position of the point, frankly it was a bit of trial and error using the radius of FAB button and it depends on each view and each design, so according to your needs, you can adjust these calculations. It was the same thing for P3 (which is the end of the first curve and the start of the second one) and P4 (the end of the second curve).

Avoid doing calculations in the onDraw()method because it is called each time and it is not good for the performance of your application. I made the calculations of my point in the onSizeChanged() method which is called when the size of the view has changed, so not too greedy in terms of performance

Now here is the most interesting and complicated part . No no, don’t worry it’s easier than you think. To begin we reset the path to clear any lines and curves from it, then we move it to the beginning point P1 using moveTo(x,y)method and draw the first line which is between P1 and P2 using lineTo(x,y)that adds a line from the last point to the specified point, and to clarify, in our case we do not really need to specify the beginning point because by default If there is no previous point, then a moveTo(0,0)is inserted automatically.

For the cubic curves, we gonna use cubicTo(x1,y1,x2,y2,x3,y3)method which allows us to draw a cubic curve, so the first and second point (x1,y1) (x2,y2) have the role of controlling the tangency. For the calculations, as you might have guessed, you have to try and grope to have the right position for your control points. To have an idea where the control points can be positioned you can try this online tool . We do the same thing for the second curve, and finally, we draw the rest of the navigation bar as if we draw a rectangle using lineTo and close the contour.

Finally, we will be able to paint using the canvas object which is the component on which we will paint. Canvas offers several drawing methods and the one that suits our use case is canvas.drawPath(Path path, Paint paint) that according to the documentation draws the specified path using the specified paint and the path will be filled or framed based on the Style in the paint.

Now I hope it’s clearer for you how to draw with android and how to have bezier curve. Happy coding

--

--