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

ShapeableImageView无法显示Shimmer占位符,仅空白直至图片加载完成

问题解决:ShapeableImageView搭配Glide Shimmer占位符不显示

ShapeableImageView的圆角是通过自身ShapeAppearanceOverlay实现的,Glide传入的ShimmerDrawable占位符不会自动继承该圆角裁剪逻辑,同时受ShapeableImageView的绘制优先级影响,导致占位符无法正常显示。以下是两种可行的解决方案:


方案一:用MaterialShapeDrawable包裹ShimmerDrawable(匹配圆角)

通过MaterialShapeDrawable给ShimmerDrawable添加和ShapeableImageView一致的圆角,确保占位符样式统一:

// 1. 构建Shimmer实例(保留原有逻辑)
val shimmer = Shimmer.AlphaHighlightBuilder()
    .setDuration(1800)
    .setBaseAlpha(0.7f)
    .setHighlightAlpha(0.6f)
    .setDirection(Shimmer.Direction.LEFT_TO_RIGHT)
    .setAutoStart(true)
    .build()

val shimmerDrawable = ShimmerDrawable().apply {
    setShimmer(shimmer)
}

// 2. 创建与ShapeableImageView一致的形状模型
// 替换成你style中定义的圆角尺寸,比如8dp对应的dimen值
val cornerSize = resources.getDimension(R.dimen.image_corner_radius)
val shapeAppearanceModel = ShapeAppearanceModel()
    .toBuilder()
    .setAllCorners(CornerFamily.ROUNDED, cornerSize)
    .build()

// 3. 用MaterialShapeDrawable包裹ShimmerDrawable,实现圆角裁剪
val shapedShimmerDrawable = MaterialShapeDrawable(shapeAppearanceModel).apply {
    paint.style = Paint.Style.FILL
    setDrawable(shimmerDrawable)
}

// 4. 加载图片时使用带圆角的Shimmer占位符
Glide.with(context)
    .load(imageUrl)
    .placeholder(shapedShimmerDrawable)
    .into(style_img)

方案二:使用ShimmerFrameLayout作为父容器(更直观)

将ShapeableImageView嵌套在ShimmerFrameLayout中,通过Glide的加载监听控制Shimmer的启停:

布局代码修改

<com.facebook.shimmer.ShimmerFrameLayout
    android:id="@+id/shimmer_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:shimmer_auto_start="true"
    app:shimmer_duration="1800"
    app:shimmer_base_alpha="0.7"
    app:shimmer_highlight_alpha="0.6"
    app:shimmer_direction="left_to_right">

    <com.google.android.material.imageview.ShapeableImageView
        android:id="@+id/style_img"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:adjustViewBounds="true"
        android:contentDescription="@string/rapturous"
        android:scaleType="centerCrop"
        android:background="@color/shimmer_light_gray" <!-- 给占位加背景色,提升可见性 -->
        app:shapeAppearanceOverlay="@style/roundedCornersImageView" />

</com.facebook.shimmer.ShimmerFrameLayout>

加载代码修改

Glide.with(context)
    .load(imageUrl)
    .listener(object : RequestListener<Drawable> {
        override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
            shimmer_container.stopShimmer()
            shimmer_container.visibility = View.GONE
            return false
        }

        override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
            shimmer_container.stopShimmer()
            shimmer_container.visibility = View.GONE
            return false
        }
    })
    .into(style_img)

额外注意事项

  1. 确保Material Components库与Shimmer库版本兼容,建议使用最新稳定版
  2. 若方案一中的圆角尺寸获取麻烦,可直接硬编码(如8f.dpToPx(),需自行实现dp转px扩展方法)
  3. 给ShapeableImageView设置浅灰色背景,避免Shimmer因背景透明导致视觉上无效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 15:58:11