如何从 Jetpack compose 中的 drawable 加载图像?

Posted

技术标签:

【中文标题】如何从 Jetpack compose 中的 drawable 加载图像?【英文标题】:How to load Image from drawable in Jetpack compose? 【发布时间】:2019-11-08 02:14:50 【问题描述】:

我尝试了下面的代码,但它在 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
                )
            
        
    

【问题讨论】:

【参考方案1】:

你可以使用painterResource函数:

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

具有给定 ID 的资源必须指向完全光栅化的图像(例如 PNG 或 JPG 文件)或 VectorDrawable xml 资产。 这意味着此方法可以分别为基于ImageBitmap 的资产或基于矢量的资产加载BitmapPainterVectorPainter 的实例。

例子:

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 获取图像资源? Picasso.load 你可以将图像视图传递给它 vectorResource,如果它是矢量图像。 并将 Coil 用于远程图像 url。 您能否指出一些解释 android 中通常使用的其他类型图像的文档。我想知道这个不支持哪种类型的图像。【参考方案2】:

从版本1.0.0-beta01开始:

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

【讨论】:

【参考方案3】:

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
      )

输出:

【讨论】:

imageResource in 不再可用【参考方案4】:

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

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

但如果需要,您实际上仍然可以使用 Bitmap 而不是 drawable:

Image(bitmap = bitmap.asImageBitmap())

.asImageBitmap() 是 compose 提供的 Bitmap 扩展,它从给定的 Bitmap 创建一个 ImageBitmap。

【讨论】:

【参考方案5】:
@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 不再可用 :(【参考方案6】:

使用版本 1.0.0-beta01

如下图

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

【讨论】:

【参考方案7】:

version=1.0.0-beta01,use painterResource,imageResource已被删除。

例子

Image(
    painterResource(R.drawable.ic_vector_or_png),
    contentDescription = null,
    modifier = Modifier.requiredSize(50.dp)
)

android developer doc

【讨论】:

【参考方案8】:

试试这个,但如果你复制代码然后粘贴它,我不知道为什么但它不起作用,所以只需按原样输入并替换图像 id

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

【讨论】:

【参考方案9】:

我从 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))
            
        
    

不过,我不确定这是从 drawables 加载图像的正确方法。

【讨论】:

【参考方案10】:

我发现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,您能分享一下参考吗? 我认为是内部的,你应该只使用 val image = imageFromResource(resources, R.mipmap.ic_launcher) 显示编译时错误,因为找不到imageFromResource。你能分享定义这个方法的内部类名吗? 您可能使用的是旧版本的 compose。我已按照此处的步骤操作:android.jlelse.eu/jetpack-compose-primer-92ff005b7ce2。 imageFromResource 函数在 androidx.ui.painting.AndroidImage.kt 中。这是:android.googlesource.com/platform/frameworks/support/+/refs/… resources 来自哪里?在这里找不到。【参考方案11】:

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 一样将图像放入容器中?

【讨论】:

以上是关于如何从 Jetpack compose 中的 drawable 加载图像?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Jetpack Compose 中的 URL 加载图像? [复制]

如何在 Jetpack compose 中检测 Horizo​​ntalPager 中的滑动?

没有从 jetpack compose 中的 rememberLauncherForActivityResult() 获取结果

如何从 Jetpack Compose TextField 关闭虚拟键盘?

Jetpack Compose 从入门到入门

Jetpack Compose 从入门到入门