Create a signature Application with Text and Draw using Jetpack Compose

HariAgusWidakdo
2 min readJan 28, 2024

Bismillah and Alhamdulillah, today I can write article again about mobile technology, especially android by using Kotlin language and Jetpack Compose library and the application I’m trying to make is about creating a Signature by text and draw. Okay, let’s get right into it.

First I try to analogize first about the design, if you see then there is a Header (Tab rows) and Content. then the code I use is as follows :

val titles = listOf("Text", "Draw")
var tabIndex by remember { mutableStateOf(0) }

Scaffold(
topBar = {
TabRow(selectedTabIndex = tabIndex) {
titles.forEachIndexed { index, title ->
Tab(
text = { Text(text = title) },
selected = tabIndex == index,
onClick = { tabIndex = index }
)
}
}
}
) { paddingValues ->
Column(
modifier = Modifier
.padding(paddingValues)
.fillMaxSize(),
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(32.dp))

when (tabIndex) {
0 -> {
SignatureText()
}

1 -> {
SignatureDraw()
}
}
}

}

Next I will focus on the first content which is SignatureText(). maybe I will explain the important code, for the whole code later you can check on my github link :

    val context = LocalContext.current
val interactionSource = remember { MutableInteractionSource() }
val bitmap: Bitmap = remember { createBitmap(640, 100) }

var text by remember { mutableStateOf(TextFieldValue()) }

val canvas = Canvas(bitmap.asImageBitmap())
val paint = Paint()

LaunchedEffect(text.text) {

// Clear image and drawing background white
canvas.nativeCanvas.drawColor(Color(0xFFF1F0EF).toArgb())
paint.color = Color.Black.toArgb()
paint.typeface = ResourcesCompat.getFont(context, R.font.fuggles_regular)
paint.textSize = 130F
paint.textAlign = Paint.Align.CENTER

// Drawing a new text
canvas.nativeCanvas.drawText(text.text, 300f, 50f, paint)
}

There may be a question, why use LaunchedEffect. yups rugh, if you don’t use LaunchedEffect then every text change will be ordered. For more details you can read here https://developer.android.com/jetpack/compose/side-effects. And for the result we can convert the bitmap into asImageBitmap() as below :

Surface(
modifier = Modifier
.fillMaxWidth()
.height(140.dp)
.padding(top = 16.dp),
color = Color(0xFFF1F0EF),
shape = RoundedCornerShape(4.dp)
) {
Column {
Text(
modifier = Modifier.padding(start = 8.dp, top = 8.dp),
text = "Signature",
fontSize = 12.sp,
color = Color(0xFF777777)
)

Spacer(modifier = Modifier.height(16.dp))

Image(
bitmap = remember { bitmap.asImageBitmap() },
contentDescription = "",
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.align(Alignment.CenterHorizontally)
)
}
}

Okay next, for the SignatureDraw I use a library from https://github.com/joelkanyi/ComposeSignature/tree/main you can check for details and it’s very easy to use

var imageBitmap: ImageBitmap? by remember { mutableStateOf(null) }

// Draw Signature
ComposeSignature(
modifier = Modifier
.fillMaxSize(),
signaturePadCardElevation = 0.dp,
signaturePadColor = Color(0xFFF1F0EF),
signaturePadHeight = 400.dp,
signatureColor = Color.Black,
signatureThickness = 10f,
onComplete = { signature ->
imageBitmap = signature.asImageBitmap()
},
)

Maybe that’s all. I hope this short article can be useful, for more detail you can check in my link github :

https://github.com/HariAgus/E-SignatureAppCompose

--

--

HariAgusWidakdo

Mobile Developer | Kotlin Developer | SwiftUI 📱. Sometimes write my story 📚