Slide 1

Slide 1 text

Yoshihiro Wada a.k.a. @e10dokup Potatotips #62 - 2019/06/18

Slide 2

Slide 2 text

Yoshihiro Wada a.k.a. @e10dokup CyberAgant Inc. / Ameba Ameba

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

1 URL 2 3 3.5

Slide 5

Slide 5 text

bumptech/glide square/picasso Image Loading Library bumptech/glide 4.9.0 ConstraintLayout

Slide 6

Slide 6 text

1 URL

Slide 7

Slide 7 text

GlideApp.with(this) .load(/* Image URL */) .placeholder(/* Placeholder Drawable */) .error(/* Error Drawable */) .into(/* Target ImageView */)

Slide 8

Slide 8 text

2

Slide 9

Slide 9 text

ConstraintLayout XML ImageView

Slide 10

Slide 10 text

centerCrop GlideApp.with(this) .load(/* Image URL */) .placeholder(/* Placeholder Drawable */) .error(/* Error Drawable */) .centerCrop() .into(/* Target ImageView */)

Slide 11

Slide 11 text

XML BindingAdapter

Slide 12

Slide 12 text

BindingAdapter BindingAdapter @BindingAdapter(“url") internal fun ImageView.loadImage(url: String?) { if (url == null) { setImageDrawable(null) return } GlideApp .with(this) .load(url) .centerCrop() .into(this) }

Slide 13

Slide 13 text

3

Slide 14

Slide 14 text

DimensionRatio

Slide 15

Slide 15 text

API URL BindingAdapter DimensionRatio 3

Slide 16

Slide 16 text

width/height dimensionRatio BindingAdapter layout_constraintDimensionRatio ConstraintLayout BindingAdapter 3 @BindingAdapter(“width”, “height”) internal fun ImageView.setAspectRatio(width: Int, height: Int) { (layoutParams as ConstraintLayout.LayoutParams).dimensionRatio = “h,${width}:${height}” }

Slide 17

Slide 17 text

glide RequestListener Drawable requestLayout() onMeasure() 3.5

Slide 18

Slide 18 text

3.5 override fun onResourceReady( resource: Drawable?, model: Any?, target: Target?, dataSource: DataSource?, isFirstResource: Boolean ): Boolean { resource ?: return false val width = resource.intrinsicWidth.toFloat() val height = resource.intrinsicHeight.toFloat() aspectRatio = width / height requestLayout() return false }

Slide 19

Slide 19 text

3.5 override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { aspectRatio?.let { // ݱঢ়ͷԣ෯Λऔಘ͠ɺ৽نʹΞεϖΫτൺΛ൓өͨ͠αΠζʹ੾Γସ͑Δ val width = MeasureSpec.getSize(widthMeasureSpec) val w = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY) val h = MeasureSpec .makeMeasureSpec((width / it).toInt(), MeasureSpec.EXACTLY) super.onMeasure(w, h) return } super.onMeasure(widthMeasureSpec, heightMeasureSpec) }

Slide 20

Slide 20 text

4

Slide 21

Slide 21 text

*NBHF7JFX *NBHF7JFX *NBHF7JFX

Slide 22

Slide 22 text

Load Bitmap Glide CenterCrop() Transformation Transformation 4:2 2 
 -> -> Transformation

Slide 23

Slide 23 text

• override fun updateDiskCacheKey(messageDigest: MessageDigest) equals() / hashCode() • override fun transform(
 pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int
 ): Bitmap toTransform Bitmap BitmapTransformation

Slide 24

Slide 24 text

override fun transform( pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int ): Bitmap { val width = toTransform.width val height = toTransform.height aspectRatio = width / height return when { aspectRatio >= 2 -> // 2:5 ΑΓԣ௕ cropWidth(pool, toTransform, imageWidth, imageHeight) else -> // ͦΕҎ֎ͷͱ͖ɺͦͷ··BitmapΛฦ٫ toTransform } }

Slide 25

Slide 25 text

private fun transform( pool: BitmapPool, toTransform: Bitmap, width: Int, height: Int ): Bitmap { val croppedWidth = (width * 0.5).toInt() return TransformationUtils.centerCrop( pool, toTransform, trimmedWidth, height ) }

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

:pray: