Android Kotlin: Paint gradient circle

Introduction

This article explores how to create a radial gradient circle in an Android application using Kotlin. The implementation involves drawing on a Canvas object, using a combination of Kotlin and Android's powerful graphics APIs. The aim is to produce a visually appealing gradient circle with smooth transitions between colors, providing a dynamic and engaging effect for Android users.

In this example, we walk through the steps involved in setting up the MainActivity, drawing the gradient circle, and displaying it in an ImageView widget. This tutorial is geared toward Android developers familiar with Kotlin, who are looking to enhance their app’s graphical capabilities by implementing custom drawing logic.

Breakdown of the Code: Activity Setup in MainActivity

The MainActivity class extends Android's Activity and serves as the main entry point for our app. In the onCreate() method, the activity's layout is set using the setContentView() method, which inflates the activity_main.xml layout. In this layout, we have an ImageView, which will be used to display the gradient circle.

To associate the ImageView widget from the XML layout with the Kotlin code, the findViewById() method is called, retrieving the reference to the ImageView. Once we have the reference, we set the content of the ImageView by calling setImageBitmap(), passing in the bitmap returned from the drawGradientCircle() function.

Drawing the Gradient Circle

The core of the gradient circle drawing logic is encapsulated in the drawGradientCircle() function. This function returns a Bitmap object, which is a representation of an image that can be drawn onto. The Bitmap.createBitmap() method is used to create a blank bitmap with dimensions of 1500x850 pixels and a color configuration of ARGB_8888, which supports transparency and 32-bit color.

Next, a Canvas object is created, associated with the newly created bitmap. The Canvas provides an interface for drawing on the bitmap, and the background color is set using the drawColor() method, which fills the canvas with a light cream color (#FEFEFA).

Defining the Gradient and Circle

To draw the circle, we first calculate its radius. The radius is set to half the smaller dimension of the canvas minus an offset of 25 pixels. This ensures that the circle fits neatly within the bounds of the canvas without touching the edges.

A Paint object is then created to define the style and color properties for drawing. The paint is configured with anti-aliasing to ensure smooth edges, and its style is set to FILL, meaning that the circle will be solid. A RadialGradient shader is applied to the paint, which defines how the colors will transition radially from the center of the circle to its edge. The gradient is defined with three colors: a deep red (#E30022), a soft cream (#F7E7CE), and a bright yellow (#FFF600). These colors transition smoothly, creating a visually striking gradient.

The shader's TileMode is set to MIRROR, which means that if the gradient extends beyond the bounds of the circle, it will mirror the colors, creating a repeated pattern. Finally, the canvas.drawCircle() method is used to draw the circle on the canvas, using the calculated center coordinates and radius, along with the configured paint.

Layout File activity_main.xml

The layout file defines a simple ConstraintLayout with an ImageView at the center. The ImageView is set to occupy the full width of its parent while adjusting its height dynamically to fit its content. This layout ensures that the gradient circle is displayed prominently in the app's UI. The background of the layout is set to a light gray color (#DCDCDC) to provide contrast with the gradient circle.

Summary

In this Kotlin Android example, we demonstrated how to draw a radial gradient circle on a canvas and display it in an ImageView. By leveraging Kotlin's Canvas, Bitmap, and Paint classes, combined with a RadialGradient shader, we were able to create a smooth and visually appealing gradient effect. This technique can be used in various scenarios where custom graphics or animations are needed in Android apps.

This tutorial provides a foundation for developers looking to incorporate custom drawing logic into their Android applications. Whether for dynamic backgrounds, UI elements, or graphical effects, the combination of Canvas and Paint offers powerful tools to create rich visual experiences.


MainActivity.kt

package com.cfsuman.kotlintutorials

import android.app.Activity
import android.graphics.*
import android.os.Bundle
import android.widget.*
import kotlin.math.min


class MainActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // get the widgets reference from XML layout
        val imageView = findViewById<ImageView>(R.id.imageView)

        // show drawing on image view
        imageView.setImageBitmap(
            drawGradientCircle()
        )
    }
}



// function to draw gradient circle on canvas
fun drawGradientCircle(): Bitmap?{
    val bitmap = Bitmap.createBitmap(
        1500,
        850,
        Bitmap.Config.ARGB_8888
    )


    // canvas for drawing
    val canvas = Canvas(bitmap).apply {
        drawColor(Color.parseColor("#FEFEFA"))
    }


    // radius of circle and gradient
    val radius = min(canvas.width, canvas.height) / 2F - 25F


    // paint to draw radial gradient circle
    val paint = Paint().apply {
        isAntiAlias = true
        style = Paint.Style.FILL

        // radial gradient shader
        shader = RadialGradient(
            canvas.width / 2F, // center x
            canvas.height / 2F, // center y
            radius, // radius
            intArrayOf( // colors
                Color.parseColor("#E30022"),
                Color.parseColor("#F7E7CE"),
                Color.parseColor("#FFF600")
            ),
            // stops - may be null, valid values are between 0.0f and 1.0f
            null,
            Shader.TileMode.MIRROR // shader titling mode
        )
    }


    // finally, draw gradient circle on canvas
    canvas.drawCircle(
        canvas.width / 2F, // cx
        canvas.height / 2F, // cy
        radius, // radius
        paint // paint to draw
    )

    return bitmap
}
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/rootLayout"
    android:background="#DCDCDC"
    android:padding="24dp">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
More android kotlin tutorials