知方号

知方号

Glide v4 : Compose<安卓 compose slide>

Compose About

Jetpack Compose is Android’s modern toolkit for building native UI. This library integrates with Compose to allow you to load images in your Compose apps with Glide in a performant manner.

Status

Glide’s Compose integration is in beta. Please submit bugs if you encounter any and/or feature requests to Glide’s Github Issues. The API is close to final. We’ll remove the ability to use subcompositions as placeholders. We may replace GlideSubcomposition with a custom Modifier. If we do so, we will deprecate GlideSubcomposition first so that you have time to migrate.

How do I include the Compose integration library?

The Compose integration doesn’t include any components, so you don’t need any changes to your AppGlideModule to use it.

Instead, just add a Gradle dependency on the Compose integration library:

implementation "com.github.bumptech.glide:compose:1.0.0-beta01"Usage

See Glide’s Gallery sample app for a small application that uses Compose and Glide’s Compose integration. See the Dokka page for detailed API documentation.

GlideImage

The primary integration point between Compose and Glide is GlideImage. GlideImage is meant to similarly to Compose’s Image function except that it uses Glide to asynchronously load images.

Simple use cases of GlideImage can include just a Model and a content description:

GlideImage(model = myUrl, contentDescription = getString(R.id.picture_of_cat))

You can supply a custom Modifier to customize how GlideImage is rendered:

GlideImage( model = myUrl, contentDescription = getString(R.id.picture_of_cat), modifier = Modifier.padding(padding).clickable(onClick = onClick).fillParentMaxSize(),)

You can also provide the alignment, contentScale, colorFilter, and alpha parameters that have identical defaults and function identically to the same parameters in Compose’s Image.

To configure the Glide load, you can provide a RequestBuilderTransformation function. The function will be passed a RequestBuilder that already has load() called on it with your given model. You can then customize the request with any normal Glide option except for Transitions (see below for details).

GlideImage( model = myUrl, contentDescription = getString(R.id.picture_of_cat), modifier = Modifier.padding(padding).clickable(onClick = onClick).fillParentMaxSize(),) { it .thumbnail( requestManager .asDrawable() .load(item.uri) .signature(signature) .override(THUMBNAIL_DIMENSION) ) .signature(signature)}Placeholders

Glide supports three types of placeholders for Compose:

Drawables Android resource IDs Painters

To specify a placeholder, use the loading and failure parameters in GlideImage. Placeholders are required to be one of Glide’s Placeholder classes:

import com.bumptech.glide.integration.compose.GlideImageimport com.bumptech.glide.integration.compose.placeholder// DrawableGlideImage(model = myUrl, loading = placeholder(myDrawable))import com.bumptech.glide.integration.compose.GlideImageimport com.bumptech.glide.integration.compose.placeholder// Resource IDGlideImage(model = myUrl, failure = placeholder(R.drawable.my_drawable))import com.bumptech.glide.integration.compose.GlideImageimport com.bumptech.glide.integration.compose.placeholder// PainterGlideImage(model = myUrl, loading = placeholder(ColorPainter(Color.Red)))

If you set a placeholder on GlideImage directly and on RequestBuilder via requestBuilderTransform, the placeholder set on GlideImage will take precedence.

Sizing

As with Glide’s View integration, Glide’s Compose integration will attempt to determine the size of your Composable and use that to load an appropriately sized image. That can only be done efficiently if you provide a Modifier that restricts the size of the Composable. If Glide determines that either the width or the height of the Composable is unbounded, it will use Target.SIZE_ORIGINAL, which can lead to excessive memory usage.

Whenever possible, make sure you either set a Modifier with a bounded size or provide an override() size to your Glide request. In addition to saving memory, loads from the disk cache will also be faster if your size is smaller.

Transitions

GlideImage as of version alpha5 supports a Compose specific Transition API. Transitions must be specified in GlideImage using the Compose API. Transitions specified in RequestBuilder will be ignored.

To cross fade from the placeholder you’ve set (if any) to the image when the load completes, use the built in CrossFade transition:

import com.bumptech.glide.integration.compose.CrossFadeGlideImage(uri, contentDescription, transition = CrossFade)

You can also write your own custom transition. If you do, please let me know by filing an issue. There’s more we can do to make this easier.

For now your best bet is to take a look at the existing CrossFade and follow a similar pattern: https://github.com/bumptech/glide/blob/2ae4effcf7bad2131a54423d203c2d124257fc04/integration/compose/src/main/java/com/bumptech/glide/integration/compose/Transition.kt#L99

Recomposition and state changes

In some rare cases, you might want to change your composition based on the state of a Glide load. You virtually never want to do this in any kind of scrolling list because doing so will incur several recompositions per image load, causing a significant amount of jank. As a rule if you can avoid using this API, you should.

That said, if you do need to recompose on state changes, you can use GlideSubcomposition:

import com.bumptech.glide.integration.compose.GlideSubcompositionGlideSubcomposition(item.uri, modifier, requestBuilderTransform = { it.thumbnail(preloadRequestBuilder)}) { // state comes from GlideSubcompositionScope when (state) { RequestState.Failure -> TODO() RequestState.Loading -> TODO() // painter also comes from GlideSubcompositionScope is RequestState.Success -> Image(painter, contentDescription = null) }}

If you have a use case that requires this API, please let me know by filing an issue. Another likely option here is to expose a Modifier based API where you could compose a custom Modifier with Glide’s and monitor Glide’s state changes via that custom Modifier. This is not yet implemented.

GlideLazyListPreloader

GlideLazyListPreloader uses Compose’s LazyListState to determine the direction the user is scrolling and preload images in the direction of scroll. Preloading, especially when used with relatively small image sizes in combination with Glide’s thumbnail API, can dramatically improve the UX of horiztonally or vertically scrolling UIs.

Using the preloader looks like this:

@Composablefun DeviceMedia(mediaStoreData: List) { val state = rememberLazyListState() LazyRow(state = state) { items(mediaStoreData) { mediaStoreItem -> // Uses GlideImage to display a MediaStoreData object MediaStoreView(mediaStoreItem, requestManager, Modifier.fillParentMaxSize()) } } GlideLazyListPreloader( state = state, data = mediaStoreData, size = THUMBNAIL_SIZE, numberOfItemsToPreload = 15, fixedVisibleItemCount = 2, ) { item, requestBuilder -> requestBuilder.load(item.uri).signature(item.signature()) }}@Composablefun MediaStoreView(item: MediaStoreData, requestManager: RequestManager, modifier: Modifier) { val signature = item.signature() GlideImage( model = item.uri, contentDescription = item.displayName, modifier = modifier, ) { it // This thumbnail request exactly matches the request in GlideLazyListPreloader // so that the preloaded image can be used here and display more quickly than // the primary request. .thumbnail( requestManager .asDrawable() .load(item.uri) .signature(signature) .override(THUMBNAIL_DIMENSION) ) .signature(signature) }}

state is a LazyListState that you can obtain using standard Compose APIs. data is the List of model objects that you’re displaying. size is the size of the image that you want to preload. This must exactly match at least one size provided to a Request or thumbnail Request used by GlideImage to display the item. numberOfItemsToPreload is total number of items you want to try to keep in memory ahead of the user’s position as they scroll. You may need some performance testing to find the right balance. Too high of a number and you may exceed the memory cache size. Too low and you won’t be able to keep up with scrolling. fixedVisibleItemCount is a guess of how many items you think will typically be visible on the screen at once.

Finally you can provide a PreloadRequestBuilderTransform, which will give you one object from the data list at a time to create a Glide request for. size will be applied for you automatically via Glide’s override API. So you only need to specify any additional components of the load that are required to make the request exactly match the load (or at least one thumbnail load) in the corresponding GlideImage.

As with much of Glide’s Compose API, there are likely to be some API changes to this class. In particular we’d like to simplify the process of specifying the request so that the request options are not duplicated, once in GlideLazyListPreloader and again in GlideImage.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至lizi9903@foxmail.com举报,一经查实,本站将立刻删除。