如何从 Jetpack Compose 中的 drawable 加载图像?
How to load Image from drawable in Jetpack compose?
我试过下面的代码,但它在 UI 中什么也没有反映,我在这里遗漏了什么?
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
)
}
}
}
}
我从 jetpack compose 库中找到 SimpleImage class 来加载图像,但这是一个临时解决方案,我还没有找到任何样式选项。
// 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))
}
}
}
}
不过,我不确定这是从可绘制对象加载图像的正确方法。
我发现imageFromResource()在AndroidImage.kt:
中有一个函数
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)
}
}
}
}
@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)
}
}
}
}
}
您可以使用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()
)
}
Google 更新了他们的 API。 0.1.0-dev03
加载图像是同步的,并且是这样完成的
val icon = +imageResource(R.drawable.ic_xxx)
绘制图像
Container(modifier = Height(100.dp) wraps Expanded) {
DrawImage(icon)
}
目前,以上代码依赖于您指定确切的高度或宽度。如果您想要例如 100 dp 高度和 wrap_content
而不是扩展整个宽度的 Expanded
,似乎不支持缩放图像。
有谁知道如何解决这个问题?也可以像旧方法一样将图像放入容器中 scaleType=fitCenter
?
在0.1.0-dev14
工作
在Image中加载drawable可以这样实现:
Image(
imageResource(id = R.drawable.scene_01),
modifier = Modifier.preferredHeightIn(160.dp, 260.dp)
.fillMaxWidth(),
contentScale = ContentScale.Crop
)
现在,我正在尝试在 Circle Image 中上传可绘制对象,这听起来很棘手,但在 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
)
输出:
从版本 1.0.0-beta01
开始:
Image(
painter = painterResource(R.drawable.your_drawable),
contentDescription = "Content description for visually impaired"
)
使用版本 1.0.0-beta01
如下图
Image(
painter = painterResource(R.drawable.header),
contentDescription = null
)
version=1.0.0-beta01,使用painterResource
,imageResource
已被删除
例子
Image(
painterResource(R.drawable.ic_vector_or_png),
contentDescription = null,
modifier = Modifier.requiredSize(50.dp)
)
由于imageResource
已经不可用了,painterResource
的解决方案确实是正确的,例如
Image(painter = painterResource(R.drawable.ic_heart), contentDescription = "content description")
但如果需要,您实际上仍然可以使用 Bitmap 而不是 drawable:
Image(bitmap = bitmap.asImageBitmap())
.asImageBitmap()
是 Compose 提供的位图扩展,它根据给定的位图创建一个 ImageBitmap。
试试这个,但如果你复制代码然后粘贴它,我不知道为什么,但它不会工作,所以只需按原样输入并替换图像 ID
Image(
painter = painterResource(id = R.drawable.tanjim),
contentDescription = null
)
我试过下面的代码,但它在 UI 中什么也没有反映,我在这里遗漏了什么?
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
)
}
}
}
}
我从 jetpack compose 库中找到 SimpleImage class 来加载图像,但这是一个临时解决方案,我还没有找到任何样式选项。
// 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))
}
}
}
}
不过,我不确定这是从可绘制对象加载图像的正确方法。
我发现imageFromResource()在AndroidImage.kt:
中有一个函数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)
}
}
}
}
@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)
}
}
}
}
}
您可以使用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()
)
}
Google 更新了他们的 API。 0.1.0-dev03
加载图像是同步的,并且是这样完成的
val icon = +imageResource(R.drawable.ic_xxx)
绘制图像
Container(modifier = Height(100.dp) wraps Expanded) {
DrawImage(icon)
}
目前,以上代码依赖于您指定确切的高度或宽度。如果您想要例如 100 dp 高度和 wrap_content
而不是扩展整个宽度的 Expanded
,似乎不支持缩放图像。
有谁知道如何解决这个问题?也可以像旧方法一样将图像放入容器中 scaleType=fitCenter
?
在0.1.0-dev14
在Image中加载drawable可以这样实现:
Image(
imageResource(id = R.drawable.scene_01),
modifier = Modifier.preferredHeightIn(160.dp, 260.dp)
.fillMaxWidth(),
contentScale = ContentScale.Crop
)
现在,我正在尝试在 Circle Image 中上传可绘制对象,这听起来很棘手,但在 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
)
输出:
从版本 1.0.0-beta01
开始:
Image(
painter = painterResource(R.drawable.your_drawable),
contentDescription = "Content description for visually impaired"
)
使用版本 1.0.0-beta01
如下图
Image(
painter = painterResource(R.drawable.header),
contentDescription = null
)
version=1.0.0-beta01,使用painterResource
,imageResource
已被删除
例子
Image(
painterResource(R.drawable.ic_vector_or_png),
contentDescription = null,
modifier = Modifier.requiredSize(50.dp)
)
由于imageResource
已经不可用了,painterResource
的解决方案确实是正确的,例如
Image(painter = painterResource(R.drawable.ic_heart), contentDescription = "content description")
但如果需要,您实际上仍然可以使用 Bitmap 而不是 drawable:
Image(bitmap = bitmap.asImageBitmap())
.asImageBitmap()
是 Compose 提供的位图扩展,它根据给定的位图创建一个 ImageBitmap。
试试这个,但如果你复制代码然后粘贴它,我不知道为什么,但它不会工作,所以只需按原样输入并替换图像 ID
Image(
painter = painterResource(id = R.drawable.tanjim),
contentDescription = null
)