16

我正在使用 Glide 将图像加载到我的 imageView(位于 recyclerview 中):

Glide.with(image.context).load(url)
        .error(context.getDrawable(R.drawable.placeholder))
        .into(image)

我看到 Glide 库还有一个“占位符”功能,它可以加载一个 Drawable,以便在图像仍在加载时显示。

另一方面,对于整个 recyclerView,我使用Facebook Shimmer库来显示正在加载 recyclerview。

查看我的应用程序,一切正常。但是,在关闭 Shimmer(获取数据)和显示图像之间仍然存在间隔时间。这正是需要占位符的时候。我想知道,有没有什么方法可以使用 Shimmer 作为 imageView 的占位符?Glide 中的 Placeholder 功能只支持 Drawable,而 Shimmer 是一个 View。

有什么方法可以将 Shimmer 转换为 Drawable?还是GIF?或者有什么其他建议?

4

3 回答 3

25

感谢 Mike 上面的评论:有一个 ShimmerDrawable 类,您可以在其中构建一个微光视图作为可在 Glide 中使用的 drawbale:

private val shimmer = Shimmer.AlphaHighlightBuilder()// The attributes for a ShimmerDrawable is set by this builder
    .setDuration(1800) // how long the shimmering animation takes to do one full sweep
    .setBaseAlpha(0.7f) //the alpha of the underlying children
    .setHighlightAlpha(0.6f) // the shimmer alpha amount
    .setDirection(Shimmer.Direction.LEFT_TO_RIGHT)
    .setAutoStart(true)
    .build()

// This is the placeholder for the imageView
    val shimmerDrawable = ShimmerDrawable().apply {
        setShimmer(shimmer)
    }


Glide.with(image.context).load(url)
        .placeholder(shimmerDrawable)
        .error(context.getDrawable(R.drawable.placeholder))
        .into(image)
于 2020-04-07T09:54:00.123 回答
3

就我而言,我想要一个带有圆角的可绘制对象作为库不支持的占位符,我发现您可以使用ShapeableImageViewGoogle Material Designs 中的一个来实现这一点。

1. 将 Google Material Designs Library 添加到您 'com.google.android.material:material:1.2.1'的 1.2.1 及以上版本的依赖项中。

2.在您的列表项视图中,将您的 ImageView 定义为 ShapeableImageView,如下所示:

<com.google.android.material.imageview.ShapeableImageView
   android:id="@+id/shapeImageView"
   android:layout_width="70dp"
   android:layout_height="70dp"
   android:background="@android:color/holo_red_dark"
   app:layout_constraintStart_toStartOf="parent"
   app:layout_constraintTop_toTopOf="parent"/>

3.在 RecyclerView.ViewHolder 类中,将上述 ShapeableImageView 的 ShapeAppearanceModel 设置为CornerFamily.ROUNDED您想要的角半径(以像素为单位),并将 ShimmerDrawable 作为 Glide 中的占位符加载,如下所示:

//initialize shimmer
val shimmer = Shimmer.ColorHighlightBuilder()
     .setBaseColor(ContextCompat.getColor(itemView.context, R.color.teal_200))
     .setBaseAlpha(0.7f)
     .setHighlightAlpha(0.7f)
     .setHighlightColor(ContextCompat.getColor(itemView.context, R.color.purple_700))
     .setDuration(1800)
     .setDirection(Shimmer.Direction.LEFT_TO_RIGHT)
     .setAutoStart(true)
     .build()

 //create ShimmerDrawable()
 val shimmerDrawable = ShimmerDrawable()
 shimmerDrawable.setShimmer(shimmer)

 //set the ShapeAppearanceModel to CornerFamily.ROUNDED and the radius in pixels
 val radius: Float = dpToPx(itemView.context, 15).toFloat();
 shapeImageView.setShapeAppearanceModel(shapeImageView.getShapeAppearanceModel()
                .toBuilder()
                .setAllCorners(CornerFamily.ROUNDED, radius)
                .build())

 //load url from Glide and add shimmerDrawable as placeholder
 Glide.with(itemView.context).load(item.url)
        .placeholder(shimmerDrawable)
        .into(shapeImageView)

使用辅助类将半径从 dp 转换为像素

fun dpToPx(context: Context, dp: Int): Int {
  return (dp * context.resources.displayMetrics.density).toInt()
}

上面的结果将是:

shimmer_rounded

于 2021-06-10T12:52:13.040 回答
2

我开发了一个库来轻松添加微光/骨架加载效果。 https://github.com/AgnaldoNP/AGSkeletonLoading

README.md 上有关于如何使用它的解释。你不需要添加一堆布局来模拟骨架,它是自动计算的。用于显示骨架的布局与显示内容相同。

如果您在布局文件上使用 SkeletonImageView,您只需调用 startLoading() 和 stopLoading() 来控制动画。我希望我对你有所帮助

于 2020-05-04T01:14:09.880 回答