如何在 Jetpack Compose 中从 drawable 加载图像?

103

我尝试了下面的代码,但在用户界面上没有反应,我错过了什么吗?

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
                )
            }
        }
    }
}
12个回答

153

您可以使用painterResource函数:

 Image(painterResource(R.drawable.ic_xxxx),"content description")

给定id的资源必须指向完全栅格化的图片(例如PNG或JPG文件)或VectorDrawable xml资源。
这意味着该方法可以加载基于ImageBitmap或基于矢量的资产的BitmapPainter实例或VectorPainter实例。

示例:

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()
    )
}

在此输入图片描述


如何通过Picasso从URL获取图像资源?您可以将ImageView传递给Picasso.load。 - Jono
6
如果是矢量图像,使用vectorResource - Daniels Šatcs
2
使用 Coil 处理远程图片 URL。 - Alt-Cat
1
你能指出一些文档,介绍在Android中通常使用的其他类型的图像吗?我想知道哪种类型的图像不受支持。 - Tushar Kathuria
1
如果有人在导入 import androidx.compose.foundation.Image 方面遇到问题 - Yash

32

从版本1.0.0-beta01开始:

Image(
    painter = painterResource(R.drawable.your_drawable),
    contentDescription = "Content description for visually impaired"
)

12

尝试这个代码,但如果您复制代码然后粘贴,我不知道为什么它不能正常工作,所以请按原样输入并替换图像ID。

Image(
  painter = painterResource(id = R.drawable.tanjim),
  contentDescription = null,
)

8

由于imageResource不再可用,使用painterResource的解决方案确实是正确的,例如:

Image(painter = painterResource(R.drawable.ic_heart), contentDescription = "content description")

但如果需要的话,实际上仍然可以使用位图(Bitmap)而不是可绘制对象(drawable):

Image(bitmap = bitmap.asImageBitmap())

.asImageBitmap()是Bitmap的扩展方法,它提供了一种从给定的Bitmap创建ImageBitmap的方式。


7

0.1.0-dev14 版本中工作

可以通过以下方式实现从图像中加载可绘制对象:

Image(
      imageResource(id = R.drawable.scene_01),
      modifier = Modifier.preferredHeightIn(160.dp, 260.dp)
                    .fillMaxWidth(),
      contentScale = ContentScale.Crop
   )

现在,我正在尝试在圆形图像中上传Drawable。这听起来很棘手,但在 JetPack Compose 中却非常容易。你可以按照以下步骤实现:

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
      )

输出:

在此输入图片描述


5
imageResource不再可用。 - MSpeed

4
版本号为1.0.0-beta01,使用painterResource,删除了imageResource。
示例
Image(
    painterResource(R.drawable.ic_vector_or_png),
    contentDescription = null,
    modifier = Modifier.requiredSize(50.dp)
)

Android 开发者文档


3

使用版本1.0.0-beta01

它看起来像这样

Image(
  painter = painterResource(R.drawable.header),
  contentDescription = null,
)

2
@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)
                }
            }
        }
    }
}

我认为DrawImage不再可用了 :( - methodsignature

1
我发现在AndroidImage.kt文件中有一个名为imageFromResource()的函数:

fun imageFromResource(res: Resources, resId: Int): Image {
    return AndroidImage(BitmapFactory.decodeResource(res, resId))
}

所以你的代码应该是:

这样写:

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

}


我无法获取AndroidImage,你能分享一下参考资料吗? - Maddy
我认为这是内部的,你应该只使用val image = imageFromResource(resources, R.mipmap.ic_launcher)。 - Mihaela Romanca
1
它显示编译时错误,因为找不到imageFromResource。你能分享一下定义此方法的内部类名吗? - Maddy
1
您可能使用的是较旧版本的Compose。我已经按照这里的步骤进行了操作:https://android.jlelse.eu/jetpack-compose-primer-92ff005b7ce2。imageFromResource函数位于androidx.ui.painting.AndroidImage.kt中。这是它的链接:https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-master-dev/ui/core/src/main/java/androidx/ui/painting/AndroidImage.kt - Mihaela Romanca
1
resources从哪里来的?这里找不到。 - Lucas Sousa
没有在任何地方看到这个。请包含这是来自哪个软件包。 - lostintranslation

0

我在jetpack compose库中发现了SimpleImage类来加载图片,但这只是一个临时解决方案,目前我还没有找到任何样式选项。

// 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())
            }
        }
    })
}

我是这样使用它的

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

不过,我不确定这是否是从可绘制对象加载图像的正确方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接