【问题标题】:How to load Image from drawable in Jetpack compose?如何从 Jetpack compose 中的 drawable 加载图像?
【发布时间】: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
                )
            }
        }
    }
}

【问题讨论】:

    标签: android image androidx android-jetpack-compose


    【解决方案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 一样将图像放入容器中?

                【讨论】:

                  猜你喜欢
                  • 2021-07-01
                  • 1970-01-01
                  • 2022-08-08
                  • 2021-11-08
                  • 1970-01-01
                  • 2023-04-02
                  • 2022-06-29
                  • 1970-01-01
                  • 2013-10-07
                  相关资源
                  最近更新 更多