Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Alex
Alex

Posted on • Edited on

     

Custom Composable with Jetpack Compose

Jetpack Compose already offers us a huge library of components to create our UI. But in order to create a more delight and custom experience to the user, we sometimes need to create our own.

In my first article series I want to talk about how to create custom views in Jetpack Compose.

On the example of a Labeled Ranged Slider we go though the steps needed to create a fully custom Composable. I chose this example because the current version of the Range Slider in Compose only offers a Float Range and no easy way to display step aligned labels, changing its appears in accordance to the selected range.

The result of this series will look like this
Labeled Range Slider in motion

We will look at three different topics used to create the Composable and in the end we put it all together.

All the code and projects will be published on GitHub as we go along.

How to draw on a Canvas

Let’s start with looking at how to draw something on a Canvas within a Composable.

As a first simple step we draw a basic shape, like a circle. To do this we

Create our Composable

  • Give it a minimum size
  • Add a Canvas
  • Draw the circle
@Composablefun DrawSimpleCircle(   color: Color,   modifier: Modifier = Modifier,   minSize: DpSize = DpSize(32.dp, 32.dp)) {   Canvas(modifier = modifier.size(minSize)) {      drawCircle(color)   }}
Enter fullscreen modeExit fullscreen mode

The result of this Composable will be a circle in the given color, filling the size of the whole Composable, e.g.

A simple green circle

Additionally this API allows us to draw our shapes not only with a single color, but also offers a more flexible Brush variant. With a Brush we are able to achieve gradients as well. The example shows a gradient with two colors, but the API allows for a variable list of colors, if desired.

...drawCircle(   brush = Brush.radialGradient(      colors = listOf(         centerColor, outerColor      )   ))
Enter fullscreen modeExit fullscreen mode

A circle with radial gradient

A Canvas in Compose can of course not only draw circles. It offers a multitude of different drawing methods. Here are examples of the offers methods and a what it might look like.

drawRect

A simple rect

drawRoundRect

Rect with rounded corners

drawLine

A simple line

drawOval

A simple oval

drawArc

An 180° arc

...drawArc(   color = color,   startAngle = 180f,  // 0f is at 3 o'clock of the circle   sweepAngle = 180f,  // go 180° from startAngle   useCenter = false,  // whether to fill the arc or not   style = Stroke(width = 2.dp.toPx()))
Enter fullscreen modeExit fullscreen mode

drawPath

An hour glass drawn with a Path

...val path = Path().apply {   lineTo(size.width, 0f)   // line from start to end   quadraticBezierTo(       // arc from the top to  bottom      size.width / 2, size.height / 2,      size.width, size.height   )   lineTo(0f, size.height)  // line from end to start   quadraticBezierTo(       // arc from bottom to top       size.width / 2, size.height / 2,      0f, 0f   )   close()                   // link end to start}drawPath(   color = color,   path = path,   style = Stroke(width = 2.dp.toPx()))
Enter fullscreen modeExit fullscreen mode

drawPoints

Five dots

drawOutline

An outlined rect

drawImage

Showing an image

...
drawImage(
image = image,
dstSize = IntSize(size.width.toInt(), size.width.toInt()),
colorFilter = ColorFilter.lighting(Color.Yellow, Color.Red)
)

Enter fullscreen modeExit fullscreen mode




Native Canvas

One useful draw function that is not offered directly within the Canvas Composable is the ability to draw a text. But we can still achieve this by using the drawIntoCanvas method. It gives us access to the native Canvas, which offers a drawText method.

Important to note: When using the native Canvas you have to resort to the android.graphics package, using its Paint or Color classes instead of the Compose variants.

Canvas(modifier = modifier.size(minSize)) {
val paint = android.graphics.Paint()
paint.textSize = textSize.toPx()
paint.color = android.graphics.Color.BLACK
drawIntoCanvas {
it.nativeCanvas.drawText(text, 0f, 0f, paint)
}
}

Enter fullscreen modeExit fullscreen mode




Conclusion

With the Canvas and the native Canvas we are able to draw everything we need for our Labeled Range Slider.

How our final result will look like

In the next part we will take a look at how we can make our custom Composable interactive, by reacting on touch events.Go directly to part 2.

The code for creating the images in this post can be found onGitHub.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

I'm a long time Software Engineer developing backend, mobile and machine learning applications, with a soft spot for Android development
  • Location
    Germany
  • Work
    Senior Software Engineer
  • Joined

More fromAlex

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp