Shares

Android Drawing App Tutorial – Pt. 1

Android Drawing App Tutorial

In this blog post, I will show you how to create Android drawing app. This blog post is part one of a two-part tutorial series where I will show you how to build simple but delightful Android drawing app.  As the name indicates, this drawing app will enable users to draw or sketch on their Android devices using their fingers.  You can get the source code for this tutorial from here. The core features of this app will include:

  1. Draw – Users will be able to draw on a blank canvas (whiteboard).
  2. Erase – Users will be able to erase what has been drawn.
  3. Undo – Users will be able to undo and redo drawing paths.
  4. Color – Users will be able to draw using a color of their choice from at least these colors: black, dark gray, light gray, blue, red, and green, orange, yellow.
  5. Share – Users will be able to capture a screen shot and email it to a friend.

Create New Project

Step 1: Create New Project – create a brand new Android Studio project, select the default minimum API which is 16, select the default Blank template. Leave the first Activity as MainActivity and click finish.

Step 2: Set Orientation – set the orientation of the MainActivity to portrait in the manifest. We will focus on creating a functional drawing app, and we will skip the concerns of handling configurations changes for now.

Step 3: Add Dimensions – we will define the dimensions that we will be using for this app in a single location which is res/values/dimen.xml, this file should already have been created for you by Android Studio, if not add one and then copy and paste the contents of this file into your dimens.xml file

Step 4: Add Colors – in a similar manner to the dimensions, copy and paste the contents of this file to your res/values/colors.xml file. Alternatively you can generate and download Material Design colors from materialpallete.com

Create Custom View

Inheritance is one of the core pillars of object oriented programming in that it gives you a head start when creating qualifying objects instead of re-inventing the wheel. The core of the work that we need to do to create an Android drawing app happens in a class we will call CustomView.java. This class will derive from the Android.view Class; by sub-classing the Android View class our Custom View class will at ounce inherit the potential to behave like every other view in Android, and we will build upon this potential to create a drawing app. Follow the following steps to implement our Custom View class.

Step 1: Add Java Class – if you have not already done so, at the root of your project add standard Java class file named CustomView.java and then have this class extend the framework’s View class ( android.view)

Step 2: Implement Constructor – once your custom view class extends the framework View class you will be prompted to implement a constructor that matches the super class. Using Android Studio quick fix shortcut (alt + enter) add the second option in the list, the one that accepts two parameters a Context and an AttributeSet and once you do the re squiggly line will go away.add_view_constructor

Step 3: Update Layout – even though all we have is a skeleton custom view, let us go ahead and make it the root view of our MainActivity. Change the root component of your content_main.xml layout file to your custom view. You will have to specify its package like below, and you can go ahead and remove the default paddings added by the template.

Step 4: Test the View – You can now run your app to test the View. As you can expect, it will be a blank screen like the one below. However, the good thing is that it did not give any error. We will now proceed to implement the use cases for this app which are draw, erase, undo, share and choose color.

Implement Drawing

Much of Android development consists of responding to events. You write code that will be executed when a particular event occurs. The system notifies you that this event has occurred through life-cycle events and listeners. To draw something on the screen, you have to respond to or override one of such events – the onDraw() event which is where every view draws itself.

In the onDraw() method you are passed the Canvas for the view that you have sub-classed, and what is a Canvas you may ask. Good thing that you asked because Canvas is one of the three components that you must understand to effectively create an Android drawing app. The other two are the Paint and the Path. So let us examine this core component, first the official definition of the Canvas.

The Canvas class holds the “draw” calls. To draw something, you need four basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, Text, Bitmap), and a paint (to describe the colors and styles for the drawing).

http://developer.android.com/reference/android/graphics/Canvas.html

canvas example

  1. Canvas – as the name implies, the Canvas is what you draw upon. It is the drawing surface for what you are drawing, and it knows how to transfer that drawing to the actual View.  The Canvas is your convenient middleman that abstracts away the nuances of writing directly to the underlying view. The Android developer guide calls it an “interface” which pretends to be “the actual surface upon which your graphics will be drawn” while in reality, it holds all of your “draw” calls and then places them into the window for you. The TwoToasters development team gave a good description of a Canvas and the other two core components in this blog post.
  2. Paint – after you obtain the surface to draw upon – the Canvas, you also need something to draw with – the Paint. As the name implies the Paint object “holds the style and color information.” It defines the “color, style, font, and so forth of each shape, you draw”.
  3. Path  – now that you have the surface to draw upon and the drawing object to use to draw upon that, you need to decide what direction that you want to draw. Do you want to go up, down, left or right. This direction is known as the Path as in a path. It provides “geometric paths consisting of straight line segments, quadratic curves, and cubic curves.” To help you better understand the concept of Path, remember that at the beginning of this post I mentioned that we would implement “Undo” which is a common feature in most drawing apps. The way we will implement it is to keep a history of every path we draw, which is anytime we go from point A to point B. So if the user wants to “Undo” their last drawing all we have to do is to remove the last entry in our list of Paths, wipe the screen clean and then re-draw everything again in that list except this time we will not re-draw that Path which has been removed. This happens at a blazing speed giving the user the illusion that we just erased the last thing they draw.

Let us now proceed to apply the concepts we learned above to our drawing. Before we start drawing, it is recommended by the Android developer guide to creating the objects that you will need for drawing ahead of time. Because creating them within the onDraw() method will degrade your app performance.

Step 1 – Add Required Components – at the top of your CustomView.java class, declare the following instance variables to represent the different components we will use for this app. I have added comments to convey what each object is used for.

Step 2 – Initialize Variables – initializing graphic objects is an expensive computational task so it is recommended that we do that before we start drawing and the best place to initialize our components is in the constructor. However, instead of cluttering the constructor, we can create a private method called init(). Go ahead and add the init() method to your CustomView.java class and below is the content of that method for now.

Step 3 – Update Constructor – with the init method in place, we can now call it from the constructor like this

Step 4 – Override onDraw – drawing for all View objects happens in the onDraw(), if we had sub-classed a View sub-class like the Button for instance, then our Custom View will in the minimum know how to draw itself as a button. Since we sub classed the view directly, we have to tell our Custom View how to draw itself via the onDraw(). Update your onDraw() method with the code below.

You can get the source code for this Tutorial from here.

Step 5: Implement OnSizeChanged – this method is called during layout when the size of this view has changed. During creation, the size of our view starts at 0 until the view rendering engine finishes calculating the size of your screen then it will call this method to update the size. Remember that when we added this view to our layout, we declared the width and height of it to match parent, well the height and width of that parent have to be calculated and the size of the view will adjust accordingly. You can essentially consider this method as part of the initialization routines of the view, and it is inside this method that we initialize our bitmap and canvas object if you don’t a Null Exception will be thrown when you try to use those objects in your onDraw method. Add this method below to your CustomView.java class file.

Step 6: Implement Touch Listener – at this point, our custom view can draw something if we call it programmatically with the appropriate X and Y coordinates. However I suspect that you did not want to create an Android drawing app that can only be told to draw through code.  The users of your app will want to move their finger on the screen and see something draw, in other for that to happen you have to register touch events as drawing actions. Your CustomView class has an onTouchEvent() method that you can override to accomplish this. Here is the code that accomplishes this:

Here is what was going on in the above code:

  1. We are passed an object of type MotionEvent
  2. Using this MotionEvent, we get the X and Y coordinates of where the touch occurred in the screen.  We store these coordinates in touchX and Y variables
  3. We then run a switch statement on the event.getAction() method which returns a result of an int.
  4. If this action evaluates to an ACTION_DOWN constant of the MotionEvent class, we know that the user just touched the screen, so we move to that point.
  5. If the int action evaluates to ACTION_MOVE, then we know that the user intents to draw, and we use our Path object to draw a line from point X to point Y
  6. If the action evaluates to ACTION_UP, then we know that the user is done, so time to transfer the drawing from the surface (Canvas) which we are drawing upon to the actual screen. And then we reset the Path object (drawPath) so that we can start afresh next time the screen is touched.
  7. When we are done, we have to notify the view that the content of what it is currently displaying has changed by calling invalidate(), this will call the onDraw() method and the screen will be repainted.

Go ahead and give it a try at this point, you should be able to draw to the screen using your finger or any other input.

Implement Erase Drawing

There are two ways we can implement erasing our drawing: we can wipe off everything on the screen and start afresh, or we can manually erase our drawing line by line. When we erase everything on the screen at once, what we are doing is essentially starting fresh and when we erase our drawing manually what we are doing, in a nutshell, is painting white color over our existing drawing to give it a resemblance of being “erased” .

There are three steps in implementing either type of our erase and for that matter any of the other operations that we want to implement such as undo, save, etc. First, we have to create a method that accomplishes each use case, then we add an icon or button or something that the user will have to click to signal the action that they want to perform, then we attach a listener to each button and when clicked we call the appropriate method.

We will place all of our drawing related icons in a bottom toolbar. Our new project template already has a top toolbar, now we want to add another toolbar to the bottom, and then we will add the icons to it.

Add Button Toolbar

Follow the steps below to add another material design toolbar to the bottom of your app.

Step 1: Update Your Layout – currently your MainActivity layout file is using Coordinator layout which then pulls in content_main.xml. We are going to change it to use RelativeLayout so we can position our bottom toolbar at the bottom. And we no longer need the Floating Action button. So go ahead and update your activity_main.xml  with the layout code below. Remember to use your package name, here it the updated layout.

Step 2: Add Icons – you will need to choose the icons you want to represent the actions you want to perform in your app. There are few sites where you can get great looking Android Icons, and I will list a few below.

  1. http://www.androidicons.com/
  2. Android Asset Studio
  3. http://icons4android.com/
  4. https://materialdesignicons.com/
  5. Google Material Icons

The icons included in this tutorial’s source code are from https://materialdesignicons.com/ all of the above options are fine, choose whichever one you like and the color you like. After you choose your icons, you have to download them and then add them to your res/resource folder.

Step 3: Add Menu – now that you have your icons you need to add them to a menu which will then inflate into our bottom toolbar. Add a menu to your res/menu folder and call it menu_drawing.xml and here is the content of the menu with entries covering the drawing operations that we want to cover.

Step 4: Add Bottom Toolbar Java Code – now that we have added a menu layout with the icons that we want to add, we need to go ahead and use Java code to inflate that menu into our bottom toolbar. Update your MainActivity.java with the following code.

Code Walkthrough – in the above code block, what we did was:

  1. Declare class instance variables for our top and button Toolbars as well as the Floating Action Button (FAB)
  2. You may want to change the Floating Action Button icon to a “+” instead of the main in XML layout
  3. We instantiated our bottom tool, added an OnMenuItemClicked listener but do not do anything with it at the moment
  4. When the FAB is clicked instead of showing the Snackbar that was added by the template, we hide FAB and show our bottom toolbar

If you run your app now, it should look like this. In the next tutorial, we will pick up from where we left.

If you like this tutorial, please share with anyone that can benefit from it and do use the comment box to leave me a comment, ask questions or provide feedback.

Keep Coding!

 


Also published on Medium.

About the Author valokafor

I am a Software Engineer with expertise in Android Development. I am available for Android development projects.

follow me on:

Leave a Comment:

14 comments
Add Your Reply