TUTORIAL WITH CODE
Custom QR scanner cutout
QR codes can be utilized to achieve a lot of different things nowadays. From opening a restaurant menu to viewing product information or paying for a snack. Sometimes QR codes are scanned with the default mobile scanner on your Android smartphone, but other times there’s a need to include a QR code scanner inside your app. There are some wonderful articles on displaying camera preview and detecting QR codes; LIke this one: link.
However, chances are that you or your client/designer will want to add an overlay over the camera preview with semitransparent background and a transparent rectangular hole in the middle. This has been the de-facto way of showing to the user that he has to scan something for some time now.
In this article, we’re gonna code a few simple QR scanner backgrounds from scratch by drawing them on Canvas. To follow this article you should have a basic understanding of how to create custom views and draw on canvas in Android.
We’ll start with the simplest QR scanner, which is just a square in the middle with a border, transparent fill, and semi-transparent background around it. The final product should look something like this:
First, we have to create a semi-transparent background. We’ll achieve this by drawing a path around the whole screen.
Secondly, we have to create the rectangle in the middle of the screen. We’ll define rectangle height and width and then calculate the positions of all the edges based on the rectangle dimensions and canvas total height and width. Then we can use those edge positions to draw a rectangular path.
The third step is to add the QR scanner path to the background path. This will ensure that the rectangle in the middle stays transparent.
This works because we added FillType.EVEN_ODD to the background Path. Android documentation states:
Specifies that “inside” is computed by an odd number of edge crossings.
Finally, we draw both of the paths to the Canvas
Let’s take this design a bit further so we create something like this:
To achieve this we first have to change the frame stroke paint to transparent and then we can draw white corners on top of the transparent frame.
By default, the path starts at 0, 0 so we first have to move to the appropriate position and then draw two straight lines to create the first corner. Repeat the process for the other three corners with appropriate coordinates.
We can also create a scanner view with rounded corners like this:
First, we have to modify the transparent cutout scanner shape so that it has rounded corners. We can do this with the help of quadTo function that draws a Bezier curve. Android documentation says:
Add a quadratic bezier from the last point, approaching control point (x1,y1), and ending at (x2,y2)
In our case, the control point should be at the corresponding corner of the transparent frame. We start to draw the left top corner by moving to the appropriate position. Then we draw the rounded corner using Path.quadTo() function and continue with the straight line to the start of the next rounded corner. We repeat the process for all the corners.
Drawing the corners to get the final look will be very similar. We just use moveTo() function instead of lineTo() function to skip drawing straight edges of the frame.
Feel free to leave a comment if you have any questions or suggestions. The full code described in this article is available on my GitHub repository.
I’m planning on implementing this example in Jetpack Compose so make sure to follow this channel if you’re interested and want to be notified when the article will be up.