How to use a 9 patch drawable (.9.png) in my screen using Jetpack Compose?
Asked Answered
M

4

8

I'm trying to use a .9.png file in Image composable as :

            Image(
            painter = painterResource(id = R.drawable.shadow_faq),
            contentDescription = "Faq card 1",
            modifier = Modifier
                .constrainAs(imgGeneral) {
                    top.linkTo(glImgGeneralTop)
                    bottom.linkTo(glImgBottom)
                    start.linkTo(glImgLeft)
                    end.linkTo(glImgRight)
                    height = Dimension.fillToConstraints
                    width = Dimension.fillToConstraints
                }
        )

But on doing this I get a render problem that says java.lang.IllegalArgumentException: Only VectorDrawables and rasterized asset types are supported ex. PNG, JPG

How do I use a .9.png file with Jetpack Compose?

Molybdate answered 9/7, 2021 at 9:32 Comment(0)
D
2

Update: Starting with 1.0.0-rc02 and accompanist 0.14.0 you can use the coil-compose version:

Image(
    rememberImagePainter(ContextCompat.getDrawable(context,R.drawable.xxx)),
    contentDescription = "Faq card 1",
)

Previous deprecated answer:
You can use the DrawablePainter from Accompanist that returns a Painter which draws an Android Drawable.

Image(
    rememberDrawablePainter(drawable = ContextCompat.getDrawable(context,R.drawable.xxxx) ),
    contentDescription = "Faq card 1"
)
Demarche answered 9/7, 2021 at 13:6 Comment(3)
Any examples how to load 9.png image without coil library ?Hortatory
I am able to load the image doing this, but it has the behaviour of a regular PNG, it doesn't resize as a 9-patch. Do I need to configure something else in the Image or the Modifier??Toffic
yeah, it doesn't resize as a 9-patch.Substratum
L
6

sometimes ,we load 9.png to be a background of Views, just like the message item on your chat apps. And we could do like this:

first we load 9.png as a drawable:

 val bgImg = ContextCompat.getDrawable(
    LocalContext.current,
    if (isFromMe) R.drawable.chat_message_right else R.drawable.chat_message_left
)

second we could use Modifier#drawBehind() method to set a background :

Text(text = "This my message",
    modifier = Modifier
        .drawBehind {
            bgImg?.updateBounds(0, 0, size.width.toInt(), size.height.toInt())
            bgImg?.draw(drawContext.canvas.nativeCanvas)
        }
        .padding(8.dp)
)

At last ,you will get the effect you want .

Landing answered 21/5, 2022 at 2:42 Comment(0)
S
4

I tried the accepted answer and didn't work for me... I'm leaving my solution here just for future reference...

First, I defined this Modifier in order to draw the 9-patch as background (I think this is the most common scenario).

fun Modifier.draw9Patch(
    context: Context,
    @DrawableRes ninePatchRes: Int,
) = this.drawBehind {
    drawIntoCanvas {
        ContextCompat.getDrawable(context, ninePatchRes)?.let { ninePatch ->
            ninePatch.run {
                bounds = Rect(0, 0, size.width.toInt(), size.height.toInt())
                draw(it.nativeCanvas)
            }
        }
    }
}

Then, you can use it in a Box for instance...

@Composable
fun NinePatchImage() {
    Box(
        Modifier.draw9Patch(LocalContext.current, R.drawable.balao)
    ) {
        Text(
            text = """
                |This is a long text to stretch the balloon
                |Diego, are you happy?
                |I know you are
                |Just one line for this
                |Yes!""".trimMargin("|"),
            Modifier
                .padding(
                    top = 24.dp,
                    bottom = 24.dp,
                    start = 32.dp,
                    end = 48.dp
                )
        )
    }
}

Here's the result: enter image description here

Scoter answered 9/7, 2021 at 13:25 Comment(3)
Did you set the size and the right contentScale?Demarche
I've set the size using Modifier. But I didn't set the contentScale...Scoter
I don't know what I've done previously... But it worked. Sorry for the confusion.Scoter
D
2

Update: Starting with 1.0.0-rc02 and accompanist 0.14.0 you can use the coil-compose version:

Image(
    rememberImagePainter(ContextCompat.getDrawable(context,R.drawable.xxx)),
    contentDescription = "Faq card 1",
)

Previous deprecated answer:
You can use the DrawablePainter from Accompanist that returns a Painter which draws an Android Drawable.

Image(
    rememberDrawablePainter(drawable = ContextCompat.getDrawable(context,R.drawable.xxxx) ),
    contentDescription = "Faq card 1"
)
Demarche answered 9/7, 2021 at 13:6 Comment(3)
Any examples how to load 9.png image without coil library ?Hortatory
I am able to load the image doing this, but it has the behaviour of a regular PNG, it doesn't resize as a 9-patch. Do I need to configure something else in the Image or the Modifier??Toffic
yeah, it doesn't resize as a 9-patch.Substratum
K
1

You can use AndroidView and pass old good ImageView

AndroidView(
    modifier = Modifier.xxx,
    factory = {
        ImageView(it)
    }
)
{
    it.setImageResource(R.drawable.shadow_faq)
}
Kazue answered 25/10, 2022 at 9:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.