Sparsh Dutta
Sparsh Dutta

Reputation: 2970

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

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?

Upvotes: 8

Views: 7415

Answers (4)

nglauber
nglauber

Reputation: 23844

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

Upvotes: 4

Gabriele Mariotti
Gabriele Mariotti

Reputation: 363439

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"
)

Upvotes: 2

user2802230
user2802230

Reputation: 11

You can use AndroidView and pass old good ImageView

AndroidView(
    modifier = Modifier.xxx,
    factory = {
        ImageView(it)
    }
)
{
    it.setImageResource(R.drawable.shadow_faq)
}

Upvotes: 1

Ronny luo
Ronny luo

Reputation: 79

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 .

Upvotes: 6

Related Questions