From e1cd4174afb51aba63102546cb6f1adf6c76a484 Mon Sep 17 00:00:00 2001 From: machiav3lli Date: Tue, 16 Nov 2021 00:48:38 +0100 Subject: [PATCH] Add: ScreenshotsAdapter --- .../droidify/screen/ScreenshotsAdapter.kt | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 src/main/kotlin/com/looker/droidify/screen/ScreenshotsAdapter.kt diff --git a/src/main/kotlin/com/looker/droidify/screen/ScreenshotsAdapter.kt b/src/main/kotlin/com/looker/droidify/screen/ScreenshotsAdapter.kt new file mode 100644 index 00000000..8667f0a4 --- /dev/null +++ b/src/main/kotlin/com/looker/droidify/screen/ScreenshotsAdapter.kt @@ -0,0 +1,135 @@ +package com.looker.droidify.screen + +import android.content.Context +import android.graphics.drawable.Drawable +import android.view.ViewGroup +import androidx.appcompat.content.res.AppCompatResources +import androidx.recyclerview.widget.RecyclerView +import coil.load +import com.google.android.material.circularreveal.CircularRevealFrameLayout +import com.google.android.material.imageview.ShapeableImageView +import com.looker.droidify.R +import com.looker.droidify.entity.Product +import com.looker.droidify.entity.Repository +import com.looker.droidify.graphics.PaddingDrawable +import com.looker.droidify.network.CoilDownloader +import com.looker.droidify.utility.extension.resources.getColorFromAttr +import com.looker.droidify.utility.extension.resources.getDrawableCompat +import com.looker.droidify.utility.extension.resources.sizeScaled +import com.looker.droidify.widget.StableRecyclerAdapter + +class ScreenshotsAdapter(private val onClick: (Product.Screenshot) -> Unit) : + StableRecyclerAdapter() { + enum class ViewType { SCREENSHOT } + + private val items = mutableListOf() + + private class ViewHolder(context: Context) : + RecyclerView.ViewHolder(CircularRevealFrameLayout(context)) { + val image: ShapeableImageView + val placeholder: Drawable + + init { + itemView as CircularRevealFrameLayout + itemView.foreground = + AppCompatResources.getDrawable(itemView.context, R.drawable.bg_item_rounded_ripple) + val surfaceColor = + itemView.context.getColorFromAttr(R.attr.colorSurface).defaultColor + + image = object : ShapeableImageView(context) { + override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec) + setMeasuredDimension(measuredWidth, measuredHeight) + } + } + + val radius = image.context.resources.getDimension(R.dimen.shape_medium_corner) + val shapeAppearanceModel = image.shapeAppearanceModel.toBuilder() + .setAllCornerSizes(radius) + .build() + image.shapeAppearanceModel = shapeAppearanceModel + image.setBackgroundColor(surfaceColor) + itemView.addView(image) + itemView.layoutParams = RecyclerView.LayoutParams( + RecyclerView.LayoutParams.WRAP_CONTENT, + RecyclerView.LayoutParams.MATCH_PARENT + ).apply { + marginStart = + image.context.resources.getDimension(R.dimen.shape_small_corner).toInt() + marginEnd = image.context.resources.getDimension(R.dimen.shape_small_corner).toInt() + } + + val placeholder = image.context.getDrawableCompat(R.drawable.ic_photo_camera).mutate() + placeholder.setTint(surfaceColor) + this.placeholder = PaddingDrawable(placeholder, 2f) + } + } + + fun setScreenshots( + repository: Repository, + packageName: String, + screenshots: List + ) { + items.clear() + items += screenshots.map { Item.ScreenshotItem(repository, packageName, it) } + notifyDataSetChanged() + } + + override val viewTypeClass: Class + get() = ViewType::class.java + + override fun getItemEnumViewType(position: Int): ViewType { + return ViewType.SCREENSHOT + } + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: ViewType + ): RecyclerView.ViewHolder { + return ViewHolder(parent.context).apply { + itemView.setOnClickListener { onClick(items[adapterPosition].screenshot) } + } + } + + override fun getItemDescriptor(position: Int): String = items[position].descriptor + override fun getItemCount(): Int = items.size + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + val context = holder.itemView.context + holder as ViewHolder + val item = items[position] + val screenWidth = context.resources.displayMetrics.widthPixels + val outer = context.resources.sizeScaled(GRID_SPACING_OUTER_DP) + val inner = context.resources.sizeScaled(GRID_SPACING_INNER_DP) + val cellSize = (screenWidth - outer - inner) / 1.5 + holder.image.load( + CoilDownloader.createScreenshotUri( + item.repository, + item.packageName, + item.screenshot + ) + ) { + placeholder(holder.placeholder) + error(holder.placeholder) + size(cellSize.toInt()) + } + } + + companion object { + private const val GRID_SPACING_OUTER_DP = 16 + private const val GRID_SPACING_INNER_DP = 8 + } + + private sealed class Item { + abstract val descriptor: String + + class ScreenshotItem( + val repository: Repository, + val packageName: String, + val screenshot: Product.Screenshot, + ) : Item() { + override val descriptor: String + get() = "screenshot.${repository.id}.${screenshot.identifier}" + } + } +}