How to load Image from drawable in Jetpack compose?
AndroidImageAndroidxAndroid Jetpack-ComposeAndroid Problem Overview
I have tried below code but it reflects nothing in the UI, I'm missing anything here?
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
loadUi()
}
}
@Composable
fun loadUi() {
CraneWrapper {
MaterialTheme {
Image(
(ResourcesCompat.getDrawable(
resources,
R.mipmap.ic_launcher,
null
) as BitmapDrawable).bitmap
)
}
}
}
}
Android Solutions
Solution 1 - Android
You can use the painterResource
function:
Image(painterResource(R.drawable.ic_xxxx),"content description")
The resources with the given id must point to either fully rasterized images (ex. PNG or JPG files) or VectorDrawable
xml assets.
It means that this method can load either an instance of BitmapPainter
or VectorPainter
for ImageBitmap
based assets or vector based assets respectively.
Example:
Card(
modifier = Modifier.size(48.dp).tag("circle"),
shape = CircleShape,
elevation = 2.dp
) {
Image(
painterResource(R.drawable.ic_xxxx),
contentDescription = "",
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize()
)
}
Solution 2 - Android
Starting at version 1.0.0-beta01
:
Image(
painter = painterResource(R.drawable.your_drawable),
contentDescription = "Content description for visually impaired"
)
Solution 3 - Android
Working in 0.1.0-dev14
Loading drawable in Image could be achieve from this:
Image(
imageResource(id = R.drawable.scene_01),
modifier = Modifier.preferredHeightIn(160.dp, 260.dp)
.fillMaxWidth(),
contentScale = ContentScale.Crop
)
Now, I'm trying to upload drawable in Circle Image that sounds tricky but too easy in JetPack Compose. You can do achieve in this way:
Image(
asset = imageResource(id = R.drawable.scene_01),
modifier = Modifier.drawBackground(
color = Color.Black,
style = Stroke(4f),
shape = CircleShape
).preferredSize(120.dp)
.gravity(Alignment.CenterHorizontally)
.clip(CircleShape),
contentScale = ContentScale.FillHeight
)
Output:
Solution 4 - Android
As imageResource
is not available anymore, the solutions with painterResource
are indeed correct, e.g.
Image(painter = painterResource(R.drawable.ic_heart), contentDescription = "content description")
But you can actually still use Bitmap instead of drawable if you need so:
Image(bitmap = bitmap.asImageBitmap())
.asImageBitmap()
is an extensions on Bitmap that compose provides and it creates an ImageBitmap from the given Bitmap.
Solution 5 - Android
version=1.0.0-beta01,use painterResource
,imageResource
has been deleted.
example
Image(
painterResource(R.drawable.ic_vector_or_png),
contentDescription = null,
modifier = Modifier.requiredSize(50.dp)
)
Solution 6 - Android
@Composable
fun loadUi() {
val image = +imageResource(R.drawable.header)
CraneWrapper {
MaterialTheme {
Container(expanded = true,height = 180.dp) {
//Use the Clip() function to round the corners of the image
Clip(shape = RoundedCornerShape(8.dp)) {
//call DrawImage() to add the graphic to the app
DrawImage(image)
}
}
}
}
}
Solution 7 - Android
With version 1.0.0-beta01
It's like below
Image(
painter = painterResource(R.drawable.header),
contentDescription = null
)
Solution 8 - Android
I found SimpleImage class from jetpack compose library to load the image but this is a temporary solution, and I didn't find any styling option with this yet.
// TODO(Andrey) Temporary. Should be replaced with our proper Image component when it available
@Composable
fun SimpleImage(
image: Image
) {
// TODO b132071873: WithDensity should be able to use the DSL syntax
WithDensity(block = {
Container(width = image.width.toDp(), height = image.height.toDp()) {
Draw { canvas, _ ->
canvas.drawImage(image, Offset.zero, Paint())
}
}
})
}
I have used it in this way
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
loadUi()
}
}
@Composable
fun loadUi() {
CraneWrapper {
MaterialTheme {
val bitmap = (ResourcesCompat.getDrawable(
resources,
R.mipmap.ic_launcher,
null
) as BitmapDrawable).bitmap
SimpleImage(Image(bitmap))
}
}
}
}
Still, I'm not sure this is the correct way of loading image from drawables.
Solution 9 - Android
I found that there is a function imageFromResource() in AndroidImage.kt:
fun imageFromResource(res: Resources, resId: Int): Image {
return AndroidImage(BitmapFactory.decodeResource(res, resId))
}
so your code would be:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
loadUi()
}
}
@Composable
fun loadUi() {
CraneWrapper {
MaterialTheme {
val image = imageFromResource(resources, R.mipmap.ic_launcher)
SimpleImage(image)
}
}
}
}
Solution 10 - Android
Try This one but if you copy the code and then paste it I don't know why but it won't work so just type it as it is and replace the image id
Image(
painter = painterResource(id = R.drawable.tanjim),
contentDescription = null
)
Solution 11 - Android
Google updated their API. For 0.1.0-dev03
loading images is synchronous and is done this way
val icon = +imageResource(R.drawable.ic_xxx)
To draw the image
Container(modifier = Height(100.dp) wraps Expanded) {
DrawImage(icon)
}
Currently the above code relies on you specifying either the exact height or width. It seems that scaling the image is not supported if you want for example 100 dp height and wrap_content
instead of Expanded
which expands the full width.
Does any one know how to solve this issue? Also is possible to fit the image inside it's container like old way scaleType=fitCenter
?