From 1fc2f8728bafb75edf8e7f97bc0eb093ff972965 Mon Sep 17 00:00:00 2001 From: WangYi Date: Thu, 2 Apr 2020 16:07:54 +0800 Subject: [PATCH] Support auto skeleton item size calculation. --- .../skeletonlayout/SkeletonExtensions.kt | 4 +- .../SkeletonRecyclerViewAdapter.kt | 54 ++++++++++++++++--- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/skeletonlayout/src/main/kotlin/com/faltenreich/skeletonlayout/SkeletonExtensions.kt b/skeletonlayout/src/main/kotlin/com/faltenreich/skeletonlayout/SkeletonExtensions.kt index 8e4351a..ae5d0ea 100644 --- a/skeletonlayout/src/main/kotlin/com/faltenreich/skeletonlayout/SkeletonExtensions.kt +++ b/skeletonlayout/src/main/kotlin/com/faltenreich/skeletonlayout/SkeletonExtensions.kt @@ -10,7 +10,7 @@ import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView import com.faltenreich.skeletonlayout.recyclerview.SkeletonRecyclerView -private const val LIST_ITEM_COUNT_DEFAULT = 3 +private const val LIST_ITEM_COUNT_AUTO = 0 /** * Creates a new Skeleton that wraps the given View in a SkeletonLayout @@ -61,7 +61,7 @@ fun View.createSkeleton( @JvmOverloads fun RecyclerView.applySkeleton( @LayoutRes listItemLayoutResId: Int, - itemCount: Int = LIST_ITEM_COUNT_DEFAULT, + itemCount: Int = LIST_ITEM_COUNT_AUTO, @ColorInt maskColor: Int = ContextCompat.getColor(context, SkeletonLayout.DEFAULT_MASK_COLOR), cornerRadius: Float = SkeletonLayout.DEFAULT_CORNER_RADIUS, showShimmer: Boolean = SkeletonLayout.DEFAULT_SHIMMER_SHOW, diff --git a/skeletonlayout/src/main/kotlin/com/faltenreich/skeletonlayout/recyclerview/SkeletonRecyclerViewAdapter.kt b/skeletonlayout/src/main/kotlin/com/faltenreich/skeletonlayout/recyclerview/SkeletonRecyclerViewAdapter.kt index 68d66ff..91bb9b4 100644 --- a/skeletonlayout/src/main/kotlin/com/faltenreich/skeletonlayout/recyclerview/SkeletonRecyclerViewAdapter.kt +++ b/skeletonlayout/src/main/kotlin/com/faltenreich/skeletonlayout/recyclerview/SkeletonRecyclerViewAdapter.kt @@ -1,6 +1,7 @@ package com.faltenreich.skeletonlayout.recyclerview import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import androidx.annotation.ColorInt import androidx.annotation.LayoutRes @@ -9,24 +10,61 @@ import com.faltenreich.skeletonlayout.SkeletonLayout import com.faltenreich.skeletonlayout.createSkeleton internal class SkeletonRecyclerViewAdapter( - @LayoutRes private val layoutResId: Int, - private val itemCount: Int, - @ColorInt private val maskColor: Int, - private val cornerRadius: Float, - private val showShimmer: Boolean, - @ColorInt private val shimmerColor: Int, - private val shimmerDurationInMillis: Long + @LayoutRes private val layoutResId: Int, + private var itemCount: Int, + @ColorInt private val maskColor: Int, + private val cornerRadius: Float, + private val showShimmer: Boolean, + @ColorInt private val shimmerColor: Int, + private val shimmerDurationInMillis: Long ) : RecyclerView.Adapter() { + private var measured = itemCount != 0 + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SkeletonRecyclerViewHolder { val originView = LayoutInflater.from(parent.context).inflate(layoutResId, parent, false) val skeleton = originView.createSkeleton(maskColor, cornerRadius, showShimmer, shimmerColor, shimmerDurationInMillis) as SkeletonLayout skeleton.layoutParams = originView.layoutParams skeleton.showSkeleton() + // Automatic calc the skeleton item count + if (!measured) { + var itemHeight = skeleton.height + var parentHeight = parent.height + val calcItemCount = { + if (itemHeight != 0 && parentHeight != 0) { + measured = true + itemCount = parentHeight / itemHeight + } + } + val listener = object : View.OnLayoutChangeListener { + override fun onLayoutChange(v: View?, left: Int, top: Int, right: Int, bottom: Int, oldLeft: Int, oldTop: Int, oldRight: Int, oldBottom: Int) { + if (top != bottom) { + skeleton.removeOnLayoutChangeListener(this) + when (v) { + skeleton -> itemHeight = bottom - top + parent -> parentHeight = bottom - top + } + calcItemCount() + } + } + } + if (itemHeight == 0) { + skeleton.addOnLayoutChangeListener(listener) + } + if (parentHeight == 0) { + parent.addOnLayoutChangeListener(listener) + } + calcItemCount() + } return SkeletonRecyclerViewHolder(skeleton) } override fun onBindViewHolder(holder: SkeletonRecyclerViewHolder, position: Int) = Unit - override fun getItemCount() = itemCount + override fun getItemCount(): Int { + return when (measured) { + true -> itemCount + else -> 1 + } + } } \ No newline at end of file