简体   繁体   English

如何在 Compose UI Android Jetpack 中将 url 加载到 Image 到 DrawImage 中?

[英]How do I load url into Image into DrawImage in Compose UI Android Jetpack?

I can use val image = +imageResource(R.drawable.header) and use DrawImage(image) to load image from Drawable Resource,我可以使用val image = +imageResource(R.drawable.header)并使用DrawImage(image)从 Drawable Resource 加载图像,

But how do I load a string url into the DrawImage(image) ?.但是如何将字符串 url 加载到DrawImage(image)中呢? I've tried using Glide, but it needs to load into imageView.我试过使用 Glide,但它需要加载到 imageView 中。 meanwhile DrawImage(image) doesn't take input from imageView.同时DrawImage(image)不接受来自 imageView 的输入。

Thanks.谢谢。

Staring with 1.0.x the best way to achieve it is to use the Coil-Compose library.1.0.x开始,实现它的最佳方法是使用Coil-Compose库。

Add in your build.gradle the dependency在您的build.gradle中添加依赖项

dependencies {
    implementation("io.coil-kt:coil-compose:1.3.1")
}

Then just use:然后只需使用:

Image(
    painter = rememberImagePainter("your url"),
    contentDescription = "My content description",
)

This loads the url passed in with rememberImagePainter , and then displays the resulting image using the standard Image composable.这会加载通过rememberImagePainter传入的url ,然后使用标准Image可组合项显示生成的图像。

Coil for Jetpack Compose Jetpack Compose 线圈

Another option to load an image from the internet.从互联网加载图像的另一种选择。

Add the Coil dependency to build.gradle :将 Coil 依赖项添加到build.gradle

dependencies {
    implementation "io.coil-kt:coil-compose:1.4.0")
}

Simple use:简单使用:

Image(
    painter = rememberImagePainter("https://picsum.photos/300/300"),
    contentDescription = stringResource(R.string.image_content_desc)
)

Don't forget to add the internet permission (AndroidManifest.xml)不要忘记添加互联网权限(AndroidManifest.xml)

<uses-permission android:name="android.permission.INTERNET"/>

More custom here: Jetpack Compose - Coil Document更多自定义: Jetpack Compose - Coil 文档

A solution loading a Bitmap from the url and using the asImageAsset() Bitmap extension method:从 url 加载位图并使用asImageAsset()位图扩展方法的解决方案:

@Composable
fun loadPicture(url: String): UiState<Bitmap> {
    var bitmapState: UiState<Bitmap> by state<UiState<Bitmap>> { UiState.Loading }

    Glide.with(ContextAmbient.current)
        .asBitmap()
        .load(url)
        .into(object : CustomTarget<Bitmap>() {
            override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                bitmapState = UiState.Success(resource)
            }

            override fun onLoadCleared(placeholder: Drawable?) { }
        })

    return bitmapState
}

Use the function with your Image() like this:像这样将函数与 Image() 一起使用:

val loadPictureState = loadPicture(url)
if (loadPictureState is UiState.Success<Bitmap>)
    Image(loadPictureState.data.asImageAsset())
else
    Text("Loading...")

This snippet is using the Glide library and the UiState helper function from the JetNews official Google sample for Jetpack Compose此代码段使用JetNews官方 Google 示例中的Glide库和UiState辅助函数,用于 Jetpack Compose

For Compose 1.1.0 this snippet works like a charm, it shows the placeholder in Composable Preview:对于 Compose 1.1.0,此代码段非常有用,它在可组合预览中显示了占位符:

@Composable
fun loadPicture(url: String, placeholder: Painter? = null): Painter? {

  var state by remember {
    mutableStateOf(placeholder)
  }

  val options: RequestOptions = RequestOptions().autoClone().diskCacheStrategy(DiskCacheStrategy.ALL)
  val context = LocalContext.current
  val result = object : CustomTarget<Bitmap>() {
    override fun onLoadCleared(p: Drawable?) {
      state = placeholder
    }

    override fun onResourceReady(
      resource: Bitmap,
      transition: Transition<in Bitmap>?,
    ) {
      state = BitmapPainter(resource.asImageBitmap())
    }
  }
  try {
    Glide.with(context)
      .asBitmap()
      .load(url)
      .apply(options)
      .into(result)
  } catch (e: Exception) {
    // Can't use LocalContext in Compose Preview
  }
  return state
}
@Composable
fun ImageItem() {
  val painter = loadPicture(
    url = item.image.fragments.image.href,
    placeholder = painterResource(id = R.drawable.tc_ic_no_image)
  )
  if (painter != null) {
    Image(painter = painter)
  }
}

You can use remember to watch a bitmap, then fetch it using Glide and update it as soon as you got it.您可以使用remember观看位图,然后使用 Glide 获取它并在获取后立即更新它。

var bitmap by remember { mutableStateOf<Bitmap?>(null)}

Glide.with(ContextAmbient.current).asBitmap()
    .load("https://picsum.photos/200/300")
    .into(object : CustomTarget<Bitmap>() {
        override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
             bitmap = resource
          }

          override fun onLoadCleared(placeholder: Drawable?) {}
      })

You can then use it like this:然后你可以像这样使用它:


if (bitmap != null )
    Image(bitmap!!.asImageAsset(), Modifier.fillMaxWidth())
else
    Text("Loading Image...")

(This is a modern version of bviale's answer ) (这是bviale 答案的现代版本)

After Jetpack's beta release, using accompanist - Utils library for Jetpack Compose is the cleanest way for the above-mentioned use case.在 Jetpack 的测试版发布后,使用accompanist - Jetpack Compose 的 Utils 库是上述用例的最干净的方法。

add添加

dependencies {
    implementation "com.google.accompanist:accompanist-glide:0.10.0"
}

and then接着

    import androidx.compose.foundation.Image
    import com.google.accompanist.glide.rememberGlidePainter
    
    Image(
        painter = rememberGlidePainter("https://picsum.photos/300/300"),
        contentDescription = stringResource(R.string.image_content_desc),
        previewPlaceholder = R.drawable.placeholder,
    )

for now you can use "io.coil-kt:coil-compose:1.3.1"现在你可以使用“io.coil-kt:coil-compose:1.3.1”

Add the Coil dependency to build.gradle:将 Coil 依赖添加到 build.gradle 中:

dependencies {
      implementation "io.coil-kt:coil-compose:1.4.0")
}

Implementation in Code:代码中的实现:

 Image(painter = rememberImagePainter(data = "https://image.tmdb.org/t/p/original/rr7E0NoGKxvbkb89eR1GwfoYjpA.jpg",
                                                builder = {
                                                    crossfade(true)
                                                    transformations(CircleCropTransformation())
                                                }),
                contentDescription = "Movie Poster")

I can use val image = +imageResource(R.drawable.header) and use DrawImage(image) to load image from Drawable Resource,我可以使用val image = +imageResource(R.drawable.header)并使用DrawImage(image)从 Drawable Resource 加载图像,

But how do I load a string url into the DrawImage(image) ?.但是如何将字符串 url 加载到DrawImage(image)中? I've tried using Glide, but it needs to load into imageView.我试过使用 Glide,但它需要加载到 imageView 中。 meanwhile DrawImage(image) doesn't take input from imageView.同时DrawImage(image)不接受来自 imageView 的输入。

Thanks.谢谢。

Try to use https://github.com/skydoves/landscapist尝试使用https://github.com/skydoves/landscapist

It seems to be realy good library to load images along with glide, coil, etc It enables to override handlers to do any custom things, eq when you got an error or during loading phase它似乎是一个非常好的库,可以加载图像以及滑行、线圈等它可以覆盖处理程序来执行任何自定义操作,例如当您遇到错误或在加载阶段时

With the latest version of Coil - 2.1.0, rememberImagePainter() has been deprecated.在最新版本的 Coil - 2.1.0 中, rememberImagePainter()已被弃用。 AsyncImage has been introduced.引入了AsyncImage

AsyncImage is a composable that that executes an image request asynchronously and renders the result. AsyncImage是一个可组合项,它异步执行图像请求并呈现结果。 It supports the same arguments as the standard Image composable and additionally it supports setting placeholder/error/fallback painters and onLoading/onSuccess/onError callbacks.它支持与标准 Image 可组合项相同的参数,此外它还支持设置占位符/错误/后备画家和 onLoading/onSuccess/onError 回调。

Below is a simple example of how to use AsyncImage to load an image from a URL:下面是一个如何使用AsyncImage从 URL 加载图像的简单示例:

AsyncImage(
    model = "https://example.com/image.jpg",
    contentDescription = null
)

You can check the docs for more comprehensive explanation of AsyncImage您可以查看文档以获得更全面的AsyncImage解释

Its support is still not added in Jetpack compose for some reason.由于某种原因,它的支持仍未添加到 Jetpack Compose 中。 But for the time being, you can use, this class但是暂时,你可以使用这个类

https://gist.github.com/nglauber/8a3c39db47813483d788fb2914f0f21f#file-image-kt https://gist.github.com/nglauber/8a3c39db47813483d788fb2914f0f21f#file-image-kt

To use it, you need to invoke it this way:要使用它,您需要以这种方式调用它:

Image(
  <your image url>,
  144.dp,
  96.dp
  )
}

You can check here to see how I used it.你可以在这里查看我是如何使用它的。 https://github.com/ranjeetsinha13/gobble/blob/f8d9bca4b010adf5b4aa59cc6e56f8612ee1de09/app/src/main/java/com/rs/gobble/ui/fragments/SearchFragment.kt#L120 https://github.com/ranjeetsinha13/gobble/blob/f8d9bca4b010adf5b4aa59cc6e56f8612ee1de09/app/src/main/java/com/rs/gobble/ui/fragments/SearchFragment.kt#L120

I can use val image = +imageResource(R.drawable.header) and use DrawImage(image) to load image from Drawable Resource,我可以使用val image = +imageResource(R.drawable.header)并使用DrawImage(image)从 Drawable Resource 加载图像,

But how do I load a string url into the DrawImage(image) ?.但是如何将字符串 url 加载到DrawImage(image)中? I've tried using Glide, but it needs to load into imageView.我试过使用 Glide,但它需要加载到 imageView 中。 meanwhile DrawImage(image) doesn't take input from imageView.同时DrawImage(image)不接受来自 imageView 的输入。

Thanks.谢谢。

I have found a very easy way to show an image from an URL.我发现了一种从 URL 显示图像的非常简单的方法。

  1. Add dependencies{ implementation("io.coil-kt:coil:1.4.0") }添加dependencies{ implementation("io.coil-kt:coil:1.4.0") }

  2. Just do this就这样做

    imageView.load("https://www.example.com/image.jpg") imageView.load("https://www.example.com/image.jpg")

Also for a resource o file you can do this:同样对于资源 o 文件,您可以这样做:

imageView.load(R.drawable.image)

imageView.load(File("/path/to/image.jpg"))

Requests can be configured with an optional trailing lambda:可以使用可选的尾随 lambda 来配置请求:

imageView.load("https://www.example.com/image.jpg") {
    crossfade(true)
    placeholder(R.drawable.image)
    transformations(CircleCropTransformation())
}

I found this info from official coil page here: enter link description here我从这里的官方线圈页面找到了这个信息:在此处输入链接描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM