Skip to content

Commit

Permalink
Fix detecting an ImageView's scale when decoding and transitioning. (#…
Browse files Browse the repository at this point in the history
…2669)

* Fix detecting an ImageView's scale when decoding and transitioning.

* Add regression test.

* Revert.
  • Loading branch information
colinrtwhite authored Nov 12, 2024
1 parent e26b782 commit 69e1395
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import coil3.util.VALID_TRANSFORMATION_CONFIGS
import coil3.util.getLifecycle
import coil3.util.isHardware
import coil3.util.safeConfig
import coil3.util.scale
import kotlinx.coroutines.Job

internal actual fun RequestService(
Expand Down Expand Up @@ -105,12 +106,22 @@ internal class AndroidRequestService(
}

private fun ImageRequest.resolveScale(size: Size): Scale {
if (defined.scale != null) {
return defined.scale
}

// Use `Scale.FIT` if either dimension is undefined.
if (size.width == Dimension.Undefined || size.height == Dimension.Undefined) {
return Scale.FIT
} else {
return scale
}

// Autodetect the scale from the ImageView.
val imageView = (target as? ViewTarget<*>)?.view as? ImageView
if (imageView != null) {
return imageView.scale
}

return scale
}

private fun ImageRequest.resolvePrecision(sizeResolver: SizeResolver): Precision {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package coil3.transition

import android.widget.ImageView
import coil3.asDrawable
import coil3.asImage
import coil3.decode.DataSource
import coil3.request.DEFAULT_CROSSFADE_MILLIS
import coil3.request.ErrorResult
import coil3.request.ImageResult
import coil3.request.SuccessResult
import coil3.size.Scale
import coil3.util.scale

/**
* A [Transition] that crossfades from the current drawable to a new one.
Expand All @@ -29,7 +32,7 @@ class CrossfadeTransition @JvmOverloads constructor(
val drawable = CrossfadeDrawable(
start = target.drawable,
end = result.image?.asDrawable(target.view.resources),
scale = result.request.scale,
scale = scale(),
durationMillis = durationMillis,
fadeStart = result !is SuccessResult || !result.isPlaceholderCached,
preferExactIntrinsicSize = preferExactIntrinsicSize,
Expand All @@ -40,6 +43,20 @@ class CrossfadeTransition @JvmOverloads constructor(
}
}

private fun scale(): Scale {
val scale = result.request.defined.scale
if (scale != null) {
return scale
}

val view = target.view
if (view is ImageView) {
return view.scale
}

return result.request.scale
}

class Factory @JvmOverloads constructor(
val durationMillis: Int = DEFAULT_CROSSFADE_MILLIS,
val preferExactIntrinsicSize: Boolean = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.widget.ImageView
import coil3.ImageLoader
import coil3.RealImageLoader
import coil3.size.Precision
import coil3.size.Scale
import coil3.size.Size
import coil3.size.ViewSizeResolver
import coil3.target.ViewTarget
Expand Down Expand Up @@ -139,7 +140,6 @@ class RequestServiceTest : RobolectricTest() {
@Config(sdk = [23])
fun `RGB_565 is preserved if hardware bitmaps are disabled`() {
val request = ImageRequest.Builder(context)
.data(Unit)
.bitmapConfig(Bitmap.Config.RGB_565)
.build()
val sizeResolver = request.defined.sizeResolver ?: service.sizeResolver(request)
Expand All @@ -154,11 +154,23 @@ class RequestServiceTest : RobolectricTest() {
.bitmapConfig(Bitmap.Config.RGB_565)
.build()
val request = ImageRequest.Builder(context)
.data(Unit)
.defaults(imageLoader.defaults)
.build()
val sizeResolver = request.defined.sizeResolver ?: service.sizeResolver(request)
val options = service.options(request, sizeResolver, Size(100, 100))
assertEquals(Bitmap.Config.RGB_565, options.bitmapConfig)
}

/** Regression test: https://github.com/coil-kt/coil/pull/2669 */
@Test
fun `ImageView scaleType sets scale`() {
val imageView = ImageView(context)
imageView.scaleType = ImageView.ScaleType.FIT_XY
val request = ImageRequest.Builder(context)
.target(imageView)
.build()
val sizeResolver = request.defined.sizeResolver ?: service.sizeResolver(request)
val options = service.options(request, sizeResolver, Size(100, 100))
assertEquals(Scale.FILL, options.scale)
}
}

0 comments on commit 69e1395

Please sign in to comment.