https://kotlinlang.org logo
#compose
Title
# compose
g

Geert

09/24/2020, 5:32 PM
What do you think about the easiest way to show a circle? Currently I have 3 options, but only 2 are working… I would prefer to use Icon and CircleShape. But that seems impossible
Copy code
// CircleShape does not work
    Image(
        asset = CircleShape,
        modifier = Modifier
            .preferredSize(16.dp)
            .background(Color.Red)
    )
    
    // Show an Circle
    Box(shape = CircleShape,
        backgroundColor = Color.Red,
        modifier = Modifier.preferredSize(16.dp)
    ) { }



    //  Material has no regular circle
    Image(
        asset = Icons.Default.AddCircle,
        modifier = Modifier
            .preferredSize(16.dp)
            .background(Color.Red)
    )
n

Nader Jawad

09/24/2020, 6:23 PM
What type is
CircleShape
?
If you just want to draw a simple shape and also have a composable participate in layout this is probably the simplest option:
Copy code
Canvas(modifier = Modifier.preferredSize(16.dp)) { drawCircle(Color.Red) }
In the first example above,
CircleShape
isn't an
ImageAsset
or
VectorAsset
so I don't think that would compile. The Box approach would work too. The last example would work if you had a vector asset that represented a circle. For the most part though the quickest way to draw anything would be to use
Modifier.drawBehind
with the drawing commands that you want and provide that on any composable modifier chain. The example, I provided using canvas is shorthand for creating a composable and automatically providing a
drawBehind
modifier on it.
m

mattinger

09/25/2020, 2:07 AM
I’m struggling as well with the lack of a useful abstraction like Drawable. I’m having to provide multiple versions of functions for ImageAsset and VectorAsset.
I did however manage to create a function to load a generic drawable from the context and turn it into an imageAsset:
Copy code
@Composable
fun drawableImageAsset(context: Context = ContextAmbient.current,
                       @DrawableRes id: Int): ImageAsset? {
    val drawable = ContextCompat.getDrawable(context, id)
    return drawable?.let { d ->
        val bm = Bitmap.createBitmap(
            d.intrinsicWidth,
            d.intrinsicHeight,
            Bitmap.Config.ARGB_8888
        )
        val canvas = Canvas(bm)
        d.setBounds(0, 0, canvas.width, canvas.height)
        d.draw(canvas)

        bm.asImageAsset()
    }
}
n

Nader Jawad

09/25/2020, 2:54 AM
Compose does have the Painter API that is the closest analogue to the Drawable API. Each compose API that takes in either an
ImageAsset
or
VectorAsset
can consume a
Painter
as well.
We have the
ImagePainter
API as well as
VectorPainter
which you can create via
ImagePainter(imageAsset)
and
VectorPainter(vectorAsset)
accordingly.
The
Image
composable consumes
Painter
instances directly but you can also draw any
Painter
as part of any other composable using the
Modifier.paint(painter)
modifier.
In your sample above @mattinger what type of Drawable are you attempt to draw? Ths sample code will work however it allocates a bitmap copy on each composition. Compose supports the equivalent of BitmapDrawable or VectorDrawable inputs. However, other framework drawable implementations would be possible to migrate by using the drawing APIs in compose via
DrawScope