Android Native - Draw Basic Shapes On Canvas

dimitrilc 1 Tallied Votes 318 Views Share

Introduction

Even though the built-in vector library included in Android Studio contains many icons readily for use, you might eventually run into a situation where a custom icon is needed. In this tutorial, we will learn how to create our own icons from basic shapes drawn on a Drawable’s Canvas.

Goals

At the end of the tutorial, you would have learned:

  1. How to draw basic shapes using custom Drawable.

Tools Required

  1. Android Studio. The version used in this tutorial is Android Studio Dolphin | 2021.3.1.

Prerequisite Knowledge

  1. Intermedia Android.

Project Setup

To follow along with the tutorial, perform the steps below:

  1. Create a new Android project with the default Empty Activity.

  2. Replace the code in activity_main.xml with the code below.

     <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <ImageView
            android:id="@+id/imageView_myImage"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:srcCompat="@tools:sample/backgrounds/scenic" />
     </androidx.constraintlayout.widget.ConstraintLayout>

At this stage, our sample application only displays a blank screen.

  • (Optional) Go to Developer options and enable Pointer Location. This will allow you to see the screen coordinates when drawing.

Overriding Drawable

Before we can draw shapes, we will need to create a custom Drawable for our ImageView. Drawable’s children are required to override the method draw(), which is where the drawing can start.

Copy and paste the following custom Drawable, either in the file MainActivity.kt or as a different file.

class BasicShapes : Drawable() {
   private val paint: Paint = Paint().apply {
       // Create your paint here
       style = Paint.Style.STROKE
       strokeWidth = 10f
       color = Color.CYAN
   }

   override fun draw(canvas: Canvas) {
       // Do your drawing here
       canvas.drawRect(
           RectF(100f, 100f, 200f, 300f),
           paint
       )
   }

   override fun setAlpha(alpha: Int) {
       // Required but can be left empty
   }

   override fun setColorFilter(colorFilter: ColorFilter?) {
       // Required but can be left empty
   }

   @Deprecated("Deprecated by super class")
   override fun getOpacity() = PixelFormat.OPAQUE
}

Drawable requires us to override many different methods, but we can just focus on the draw() method and leave everything else as default.

The Paint object located in our custom implementation is also important. We need it to be able to draw anything.

Even though we do not have any useful implementation of draw() yet, it is fine to use BasicShapes as the drawable of the ImageView. Append the code below to onCreate().

findViewById<ImageView>(R.id.imageView_myImage)
   .setImageDrawable(BasicShapes())

Drawing A Rectangle

One more thing that we need to understand before we can draw on a Canvas is the coordinate system. A View’s top left corner always have a (0x, 0y) coordinates, which also means that the bottom right corner contains (maxX, maxY) coordinates.

Screen_Shot_2022-10-14_at_9.54.46_AM.png

In most cases, we will have to provide the coordinates when drawing on Canvas.

To draw a Rectangle, we would use the drawRect() method from the Canvas object passed to onDraw().

override fun draw(canvas: Canvas) {
   // Do your drawing here
   canvas.drawRect(
       Rect(
           100, // distance from left of view
           100, // distance from top of view
           400, // distance from left of view
           300 // distance from top of view
       ),
       paint
   )
}

The code above will draw a rectangle (check code comments), as the screenshot below illustrates.

Screenshot_1665761209.png

Draw More Basic Shapes

Once you have figured out the coordinate system, drawing other shapes is only a matter of applying basic geometry on the appropriate methods.

  • A circle can be drawn using drawCircle().
  • An oval can be drawn using drawOval().
  • A square can be drawn using drawRect() with appropriate dimensions.

The code below adds a circle, an oval and a square to our application.

override fun draw(canvas: Canvas) {
   // Do your drawing here
   canvas.drawRect(
       Rect(
           100, // distance from left of view
           100, // distance from top of view
           400, // distance from left of view
           300 // distance from top of view
       ),
       paint
   )

   canvas.drawCircle(300f, 500f, 100f, paint)
   canvas.drawOval(
       RectF(100f, 700f, 500f, 800f),
       paint
   )
   // square
   canvas.drawRect(
       Rect(
           500, // distance from left of view
           100, // distance from top of view
           700, // distance from left of view
           300 // distance from top of view
       ),
       paint
   )
}

The app should look like the screenshot below.

Screenshot_1665762591.png

Summary

We have learned how to draw basic shapes in this tutorial. The full project code can be found at https://github.com/dmitrilc/DaniwebAndroidDrawBasicShapesOnCanvas.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.