Quickdraw Spec Sheet
CSUMB – Spring ‘19A – CST 338
Bodey Provansal
Summary
For my final project I decided to make an Android app inspired by a popular technique in
learning how to draw. My idea came from the recent popularity of drawing prompt books. Which are
notebooks that on each page give a prompt for something new to draw. The idea is for a either a
beginner or more advanced artist to “loosen up” by not having to think of what they are going to try
to draw.
So, I designed the starting point of an app that would allow users to be able to do this on the
go, but with the added features of a digital drawing device. The app includes a drawing board, a
randomized palette of colors, a random drawing prompt, and a timer to keep ideas flowing quickly.
Flow
The intended flow of the app.
1) The user opens the app to a blank drawing board, palette, and prompt, with the timer set to
0:00.
2) After pressing the “New Idea” button. They will be given a random color palette and drawing
prompt chosen from our resources. The timer will be set to 1:00 and begin counting down.
3) While the timer is counting down, they are free to move on to a new idea by pressing the
“New Idea” button. This will have the same effect, randomizing the prompt and palette
while also restarting the timer. Effectively starting a new “round” of drawing.
4) After the timer ends, a dialog will appear asking the user whether or not they want a new
idea. A “Yes” option will function the same as pressing the “New Idea” button. A “No”
option will close the dialog and allow the user to keep working on their current drawing.
They then have as much time as they want to continue drawing and close the app or start a
new round of drawing.
Specifications
XML
Layout
Everything in the app should fit in one vertical Linear Layout. This layout is separated into 3
sections going in order from the top of the screen to bottom:
1) A horizontal Linear Layout containing first the “New Idea” button and the field that will hold
a TextView that contains the new drawing prompt.
2) The next two items do not need to be in their own separate Linear Layout. First, is a space
for the TextView that displays the countdown timer for the current “round” of drawing.
Second, is where we will place the actual drawing board, or DrawView.
3) Finally, there will be another horizontal Linear Layout. This will contain our color buttons.
From left to right, there will be a button for a Primary Color (Red, Blue, Yellow), Secondary
Color (Green, Purple, Orange), and a Shading Color(Black, White, Light/Dark Gray). This won’t
make the prettiest combinations at first, but we can later add new colors and pre-chosen
palettes if we want.
Resources
• Strings.xml – The strings xml will hold the following resources
1) Content Descriptions for all Android Components
2) Text for our New Idea Button
3) Text for our Dialog, including title and messages.
4) Most importantly, all of our idea prompts. The names of resource tags should match their
position in the xml file, not a reference to the content. (e.g. if “Apple” is first the tag
should look like <string name”string1”>Apple</string> this will be how we load the
strings later.)
• Colors.xml – This will contain all of our colors.
2
1) For now, our colors our chosen and placed in an array when our main file is initialized.
And are only chosen by Primary, Secondary, and Shading colors as an example for the
assignment. But we can later pick out specific matching palettes using this file.
Java
DrawView.java
Our class DrawView will be a new Android component that extends View. It will handle
everything occurs when the user touches this View. First, we will initialize the components of the
View. Privately declaring our Path, Paint, Bitmap, and Canvas objects. We will need two Paint objects.
(userPaint stores the user’s paint information and boardPaint allows us to write to our Bitmap) When
the user touches the screen a “path” will be started following their fingers. A paint color will be
applied to that path, written to the canvas and displayed by the bitmap. The bitmap defines the
parameters for the space we can draw on while the canvas provides us the methods we use to do
the drawing. Paint and Path define the properties of how we are drawing to the screen. When they
release that path is reset, and we wait until they touch again to create another path on the canvas.
We can then declare our primitives. First is a private int called drawColor. This is a default
transparent drawing color used if the user touches the canvas before pressing the New Idea button
for the first time. Next is two private floats x and y. They will be used to track the user’s finger
position.
Public void createDrawingBoard()
Moving on to our methods, our default constructor takes in two parameters; the current context
and the attributes of our view object. Our constructor calls the superconstructor, passing both
parameters and calls our createDrawingBoard() method that initializes our DrawView.
createDrawingBoard() creates our Path and Paint objects while setting up what our Paint will look
like when our users drags their finger across the screen. The Paint is set to the current drawColor.
Style set to STROKE, join set to ROUND, cap set to SQUARE, and width set to 20. We must also
initialize our boardPaint object by giving it the parameter Paint.DITHER_FLAG, allowing it to write to
the Bitmap.
Public Boolean onTouchEvent(MotionEvent e)
We have to Override a few methods including what happens when our users touches the drawing
board. Touching the view creates a MotionEvent e. we can get the x and y location on the view using
getX() and getY(), allowing us to follow the user’s finger. Drawing will take place in 3 steps:
ACTION_DOWN, ACTION_MOVE, and ACTION_UP. This corresponds to the user touching the screen,
dragging their finger across the screen and lifting their finger off the screen. During each one of
these steps we update the path to include every x and y location they pass through. Once they lift
their finger from that spot, we should add that position to our path. Once the position is stored into
the path we can use the canvas to paint that position with our current paint Object (which includes
style and color). After taking their finger off of the screen, the path should be reset.
Public void onSizeChanged(int width, int height, int oldWidth, int oldHeight)
3
Another Override method. Uses the parent method super.onSizeChanged(), passing in the
parameters. This is a necessary method that will change the size of our view if the app is loaded onto
a device with a different screen size. It will do its best to configure our layout accordingly. We then
also use these width and height parameters to define and create our Bitmap and Canvas. The Bitmap
fits over our DrawView when created. And our canvas is assigned that bitmap to edit.
Public void onDraw(Canvas canvas)
Another Override method. When an onDraw call is made to this View, it will take in our Canvas
object. It will draw onto our bitmap, and then apply our path and paint properties using
canvas.drawPath(Path, Paint).
Public void clearCanvas()
This is the method that will erase our user’s drawing when a new round is called. We first reset our
path, erasing whatever color and positions we have stored. After, we tell the canvas to draw a
transparent color over the entire canvas using the PorterDuff mode, CLEAR. This doesn’t just draw
over our currently drawn pixels but replaces or clears them with a transparent color.
Public void setUserPaint(int newColor) /public int getUserPaint
Finally, we have an accessor and mutator for the userPaint.
MainActivity.Java
Our main activity is what runs our UI thread, so it will contain any logic used to
function the buttons and textViews. It extends AppCompatActivity to include information
from our Android components. It also implements View.OnclickListener to allow onClick
events to be called with our UI buttons.
All of our variables will be private. First, we initialize our objects. We will have one regular
Button, ideaButton. Three ImageButtons: colorBtn1, colorBtn2, colorBtn3. Two TextViews, ideaText
and timerText. Our DrawView object that we extended form View. We will also declare a Drawable
object that will help us get the current color our colorBtns are showing. We will also use a builtin
Android object CountDownTimer for our timer. Finally, a Random object named rand.
Our primitives will include two ints newColor and time. They will hold the current color and
countdown time. We will have a Boolean flag firstRound to know if the newIdea button has been
pressed before. Most of our content will be stored in the next four int arrays. ideaArr will hold the
id’s of the strings for our drawing prompts. The order MUST match the order they are given in our
strings.xml file.
We then declare int arrays for each of our color buttons. A primColorArr, secdColorArr, and
shadeColorArr. This is where we choose what colors will be used in our randomized palette. Each
button gets its own array or colors. For this example I have chosen a private int array filled with 3-5
colors. The first button will be 3 primary colors, accessed by referencing our resources folder
4
i.e. private int[] primColorArr = {R.color.red, R.color.blue, R.color.yellow};
And did the same for secondary (Button 2) and shading colors. (Button 3).
Protected void onCreate(Bundle savedInstanceState)
First, we will Override the standard onCreate method to also include our init() method and the
method that will create, but not start, our countdown timer.
Public void Init()
This method matches up our component objects with their resource ids, creates our Random object,
and assigns onClickListeners to all of the buttons.
Public void onClick(View v)
Overridden method. Takes in the current View and should react appropriately if the component with
a matching resource id is clicked.
If R.id.idea button is clicked, we start a new round. This involves:
1) Getting and setting our new drawing prompt.
2) Getting and setting a new palette of colors.
3) Setting the user’s current color to the first new color that we choose. This is so they are
not left with the last color they had from the previous round.
4) If this is not the start of the first round and they pressed the button in the middle of a
round, we will kill our current timer.
5) Make a new timer, then start it.
6) Confirm this is no longer the first round.
All the color buttons onClick method function the same. We first assign our btnBackground
Drawable to the background of whatever button we clicked on. After casting this Object to a
ColorDrawable we can obtain whatever color it is using getColor(). Using this value, we can call the
method from drawView to set the new user paint color.
Public void newIdea()
In this method we use our Random object to create a number within the range of our total number
of drawing prompt ideas. We then set the Prompt TextView to a random entry in the ideaArr array.
Public void newColors()
Similarly, we will use the same method to randomly select a new color for each button.
Public void makeTimer()
This method resets our time to 60 seconds and sets our variable timer to a new CountDownTimer
object. This object ticks every second for 60 seconds, decrementing the time value on each tick.
When the timer reaches 0, it will call the TimesUpDialog. This method does not start the timer,
however, as we don’t want it to start running the moment that it’s created when the app first starts.
5
Public void stopTimer()
Kills the current timer and helps reset the TextView.
Public void timesUpDialog()
Creates a new dialog object using Android.AlertDialog.Builder. We first set a title and message to the
Dialog option that pops up when our timer reaches zero. The dialog gives a Positive option and a
Negative option. Each one is displayed by a button with a Listener applied. The Negative option will
simply dismiss the dialog, allowing the user to continue their drawing with no time limit. A positive
click will do all of the same steps and beginning a new round. It will kill, create, and start a new timer,
clear the drawView, while also resetting the colors and prompt.