You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用TransitionDrawable实现Drawable淡入淡出,能否保持宽高比?

解决TransitionDrawable背景过渡时图片拉伸/挤压的问题

问题根源

  1. 代码末尾的backgroundimage.setImageResource(imageResource)会直接覆盖你设置的TransitionDrawable,导致过渡效果被打断,最终显示未经过缩放处理的原图,这是图片拉伸的核心原因。
  2. TransitionDrawable中的新旧Drawable未统一缩放规则,即使ImageView设置了CENTER_CROP,内部Drawable的显示逻辑可能不匹配。
  3. 原代码用同步get()加载Bitmap会阻塞主线程,存在ANR风险。

修正方案

移除覆盖TransitionDrawable的代码,统一新旧Drawable的缩放逻辑,改用异步加载避免主线程阻塞,修正后的代码如下:

val imageResource = setSpecialImage(principalEvent)
if (isFirstTimeLoadingBackground) {
    isFirstTimeLoadingBackground = false
    // 首次加载直接用Picasso处理,保证初始图片应用正确缩放
    backgroundimage.scaleType = ImageView.ScaleType.CENTER_CROP
    Picasso.get().load(imageResource)
        .fit()
        .centerCrop()
        .into(backgroundimage)
} else {
    // 获取ImageView实际尺寸,而非屏幕尺寸(适配非全屏场景)
    val targetWidth = backgroundimage.width
    val targetHeight = backgroundimage.height

    // 异步加载新图片,避免阻塞主线程
    Picasso.get().load(imageResource)
        .resize(targetWidth, targetHeight)
        .centerCrop()
        .into(object : Target {
            override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) {
                bitmap?.let {
                    val newDrawable = BitmapDrawable(resources, it).apply {
                        // 设置gravity与ImageView的scaleType保持一致
                        gravity = Gravity.CENTER_CROP
                    }
                    val oldDrawable = backgroundimage.drawable
                    val transition = TransitionDrawable(arrayOf(oldDrawable, newDrawable))
                    backgroundimage.setImageDrawable(transition)
                    backgroundimage.scaleType = ImageView.ScaleType.CENTER_CROP
                    transition.startTransition(100)
                }
            }

            override fun onBitmapFailed(e: Exception?, errorDrawable: Drawable?) {
                // 加载失败时降级处理
                backgroundimage.setImageResource(imageResource)
            }

            override fun onPrepareLoad(placeHolderDrawable: Drawable?) {}
        })
}

关键优化点

  • 移除了backgroundimage.setImageResource(imageResource),保证过渡效果完整执行。
  • 用ImageView自身尺寸替代屏幕尺寸,适配非全屏的ImageView场景。
  • 异步加载Bitmap,避免主线程阻塞。
  • 给新Drawable设置Gravity.CENTER_CROP,确保新旧Drawable的缩放逻辑完全统一,过渡过程中不会出现拉伸挤压。

内容的提问来源于stack exchange,提问作者LiamTheKid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 09:25:08