Skip to content

Instantly share code, notes, and snippets.

@AndSky90
Created November 16, 2019 13:49
Show Gist options
  • Save AndSky90/42843b695dafd8cfe07645f5af95dfb8 to your computer and use it in GitHub Desktop.
Save AndSky90/42843b695dafd8cfe07645f5af95dfb8 to your computer and use it in GitHub Desktop.
Glide
class GlideMaskTransformation(private val maskId: Int) : Transformation<Bitmap> {
private val id = "MaskTransformation"
private val paint = Paint().apply { xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN) }
override fun transform(
context: Context, resource: Resource<Bitmap>,
outWidth: Int, outHeight: Int
): Resource<Bitmap> {
require(Util.isValidDimensions(outWidth, outHeight)) { "Cannot apply transformation on width: $outWidth or height: $outHeight" }
val bitmapPool = Glide.get(context).bitmapPool
val toTransform = resource.get()
val transformed = transformBitmap(context.applicationContext, bitmapPool, toTransform)
return if (toTransform == transformed) resource
else BitmapResource.obtain(transformed, bitmapPool) as Resource<Bitmap>
}
private fun transformBitmap(context: Context, pool: BitmapPool, toTransform: Bitmap): Bitmap {
val width = toTransform.width
val height = toTransform.height
val bitmap = pool.get(width, height, Bitmap.Config.ARGB_8888)
bitmap.setHasAlpha(true)
val mask = getMaskDrawable(context.applicationContext, maskId)
val canvas = Canvas(bitmap)
mask.setBounds(0, 0, width, height)
mask.draw(canvas)
canvas.drawBitmap(toTransform, 0f, 0f, paint)
return bitmap
}
override fun toString() = "MaskTransformation(maskId=$maskId)"
override fun equals(other: Any?) = other is GlideMaskTransformation && other.maskId == maskId
override fun hashCode() = id.hashCode() + maskId * 10
override fun updateDiskCacheKey(messageDigest: MessageDigest) {
messageDigest.update((id + maskId).toByteArray(CHARSET))
}
private fun getMaskDrawable(context: Context, maskId: Int) =
context.getDrawable(maskId) ?: throw IllegalArgumentException("maskId is invalid")
}
object GlideTools {
private lateinit var appGlide : Glide
fun init(value : Glide) {
appGlide = value
}
/**настройка анимации появления изображений*/
private val drawableTransitionFactory: DrawableCrossFadeFactory =
DrawableCrossFadeFactory.Builder().setCrossFadeEnabled(true).build()
/**подстановка данных авторизации в запросы к API*/
private fun createHeader() = LazyHeaders.Builder()
.addHeader("tenant", TenantProvider.tenant)
.addHeader("Authorization", AuthProvider.getAuthHeaderValue())
.build()!!
fun setMenuItemIconWithGlide(
context: Context,
imageLink: Any?, // URI/URL изображения
errorImage: Int,
menuItem: MenuItem?
) {
if (imageLink == null) menuItem?.setIcon(errorImage) else
Glide.with(context)
.load(
if (imageLink is String? && URLUtil.isValidUrl(imageLink))
GlideUrl(imageLink, createHeader())
else imageLink
)
.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Drawable>?,
isFirstResource: Boolean
): Boolean {
menuItem?.setIcon(errorImage)
return false
}
override fun onResourceReady(
resource: Drawable?,
model: Any?,
target: Target<Drawable>?,
dataSource: DataSource?,
isFirstResource: Boolean
): Boolean {
if (resource != null) menuItem?.icon = resource
else menuItem?.setIcon(errorImage)
return false
}
})
.diskCacheStrategy(DiskCacheStrategy.ALL)
.dontAnimate()
.submit()
}
fun setImageWithGlide(
imageLink: Any?, // URI/URL изображения
imageView: ImageView, //вью, в котором отображать изображение
/*опциональные поля*/
maskImage: Int? = null,
onFailed: () -> Unit = {}, //лямбда, вызываемая при ошибке загрузки изображения
errorImage: Int? = null, //изображение, отображаемое в случае ошибки
fallbackImage: Int? = null, //изображение, отображаемое в случае null основной ссылки
placeholderImage: Int? = null, //изображение, отображаемое в процессе загрузки основного изображения
isRoundCrop: Boolean = false, //применяет круговую маску к изображению
isCenterCrop: Boolean = true, //применяет centerCrop к изображению
cachingSignature: Any? = null //применять, когда измененное изображение не обновляется
) {
imageView.visibility = View.VISIBLE
if (imageLink == null && errorImage == null) {
onFailed()
} else {
Glide.with(imageView)
.load(
if (imageLink == null) errorImage
else if (imageLink is String? && URLUtil.isValidUrl(imageLink))
GlideUrl(imageLink, createHeader())
else imageLink
)
.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Drawable>?,
isFirstResource: Boolean
): Boolean {
/* если errorImage указан, то onFailed не выполнится*/
if (errorImage != null) {
imageView.setImageResource(errorImage)
} else {
onFailed()
@Suppress("ConstantConditionIf")
if (USER_LOGGING_ENABLED) e?.logRootCauses("===SibLog===")
log("glide exception $e")
}
return true
}
override fun onResourceReady(
resource: Drawable?, model: Any?, target: Target<Drawable>?,
dataSource: DataSource?, isFirstResource: Boolean
): Boolean {
return false
}
})
.diskCacheStrategy(DiskCacheStrategy.ALL)
.apply {
if (cachingSignature!=null) signature(ObjectKey(cachingSignature))
if (fallbackImage != null) fallback(fallbackImage)
if (placeholderImage != null) placeholder(placeholderImage)
}
.apply {
when {
maskImage != null -> apply(
bitmapTransform(
MultiTransformation<Bitmap>(
CenterCrop(),
GlideMaskTransformation(maskImage)
)
)
)
isRoundCrop -> apply(RequestOptions.circleCropTransform())
isCenterCrop -> centerCrop()
}
}
.transition(withCrossFade(drawableTransitionFactory))
.into(imageView)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment