diff --git a/coil-core/src/androidMain/kotlin/coil3/request/RequestService.android.kt b/coil-core/src/androidMain/kotlin/coil3/request/RequestService.android.kt index 67e976e89d..523fb41335 100644 --- a/coil-core/src/androidMain/kotlin/coil3/request/RequestService.android.kt +++ b/coil-core/src/androidMain/kotlin/coil3/request/RequestService.android.kt @@ -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( @@ -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 { diff --git a/coil-core/src/androidMain/kotlin/coil3/transition/CrossfadeTransition.kt b/coil-core/src/androidMain/kotlin/coil3/transition/CrossfadeTransition.kt index 82510e3da3..c316a199cc 100644 --- a/coil-core/src/androidMain/kotlin/coil3/transition/CrossfadeTransition.kt +++ b/coil-core/src/androidMain/kotlin/coil3/transition/CrossfadeTransition.kt @@ -1,5 +1,6 @@ package coil3.transition +import android.widget.ImageView import coil3.asDrawable import coil3.asImage import coil3.decode.DataSource @@ -7,6 +8,8 @@ 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. @@ -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, @@ -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, diff --git a/coil-core/src/androidUnitTest/kotlin/coil3/request/RequestServiceTest.kt b/coil-core/src/androidUnitTest/kotlin/coil3/request/RequestServiceTest.kt index 35650814f8..b4c6fbc574 100644 --- a/coil-core/src/androidUnitTest/kotlin/coil3/request/RequestServiceTest.kt +++ b/coil-core/src/androidUnitTest/kotlin/coil3/request/RequestServiceTest.kt @@ -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 @@ -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) @@ -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) + } }