Android Kotlin - How to draw dotted line on a Canvas
This code demonstrates how to draw a dotted line on a canvas in an Android app written in Kotlin. It utilizes an ImageView
to display the line and a SeekBar
to control the width of the dots.
Explanation:
MainActivity.kt:
- The
onCreate
method sets up the UI elements, including theImageView
andSeekBar
. - It calls the
drawDottedLine
function with the initial dot width (progress + 10) to create a bitmap with the dotted line. This bitmap is then set to theImageView
. - A
SeekBar.OnSeekBarChangeListener
is implemented to update the dotted line whenever the user adjusts the seekbar. The listener retrieves the new progress value, generates a new bitmap with the updated dot width, and sets it back to theImageView
.
- The
drawDottedLine function:
- This function takes an optional
dotWidth
parameter (default 25f) and creates a new bitmap with a specified size and ARGB_8888 config (supports transparency). - It creates a
Canvas
object from the bitmap and sets a background color. - A
Paint
object is configured with anti-aliasing, desired color, stroke width, round stroke cap, and aDashPathEffect
to create the dotted line pattern. TheDashPathEffect
takes an array of floats defining the lengths of on and off segments for the dotted line. Here, it creates a nearly rounded dot by setting on segment to one-twelfth of the dot width and the off segment to twice the dot width. - A
Path
object defines the line path. It starts at a point and uses a quadratic bezier curve to draw a curved line across the canvas. - Finally, the
drawPath
method on the canvas draws the defined path with the configured paint, resulting in the dotted line on the bitmap.
- This function takes an optional
activity_main.xml:
- This layout file defines the user interface for the activity. It uses a ConstraintLayout to position the
ImageView
andSeekBar
elements. TheImageView
fills the width of the screen and wraps its height to fit the content. TheSeekBar
is placed below theImageView
and allows the user to adjust the dot width within a range of 0 to 200.
- This layout file defines the user interface for the activity. It uses a ConstraintLayout to position the
MainActivity.kt
package com.cfsuman.kotlintutorials
import android.app.Activity
import android.graphics.*
import android.os.Bundle
import android.widget.ImageView
import android.widget.SeekBar
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)
val seekBar = findViewById<SeekBar>(R.id.seekBar)
// show initial drawing on image view
imageView.setImageBitmap(
drawDottedLine(seekBar.progress + 10F)
)
// update drawing on seek bar change
seekBar.setOnSeekBarChangeListener(object :
SeekBar.OnSeekBarChangeListener{
override fun onProgressChanged(
seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
val bitmap = drawDottedLine(progress + 10F)
imageView.setImageBitmap(bitmap)
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
}
})
}
}
// function to draw dotted line on canvas
fun drawDottedLine(
dotWidth : Float = 25F
):Bitmap?{
val bitmap = Bitmap.createBitmap(
1500,
850,
Bitmap.Config.ARGB_8888
)
// canvas for drawing
val canvas = Canvas(bitmap).apply {
drawColor(Color.parseColor("#A2A2D0"))
}
// paint to draw dotted line
val paint = Paint().apply {
isAntiAlias = true
color = Color.parseColor("#333399")
strokeWidth = dotWidth
style = Paint.Style.STROKE
strokeCap = Paint.Cap.ROUND
pathEffect = DashPathEffect(
// try to make nearly rounded shape / dot
floatArrayOf
(dotWidth / 12,
dotWidth * 2
),
0F // phase
)
}
// draw a line path
val path = Path().apply {
// move to line starting point
moveTo(100F,canvas.height / 2F)
// draw line
// add a quadratic bezier
quadTo(
100F, // x1
canvas.height / 2F, // y1
canvas.width - 100F, // x2
canvas.height / 2F // y2
)
}
// finally, draw the path (dotted line) on canvas
canvas.drawPath(path, paint)
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:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
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" />
<SeekBar
android:id="@+id/seekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:max="200"
android:progress="20"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
</androidx.constraintlayout.widget.ConstraintLayout>
- android kotlin - RadioButton circle color programmatically
- android kotlin - TextView margin programmatically
- android kotlin - Create TextView programmatically
- android kotlin - TextView add border programmatically
- android kotlin - Coroutines get html from url
- android kotlin - Coroutines JSON from URL
- android kotlin - Coroutines with LiveData
- android kotlin - Coroutines async await all
- android kotlin - Coroutines cancel job
- android kotlin - Coroutines start undispatched
- android kotlin - Coroutines delay
- android kotlin - Canvas draw dashed line
- android kotlin - Canvas draw point
- android kotlin - Canvas erase drawing
- android kotlin - Canvas draw text shadow