Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,22 @@ import com.faltenreich.skeletonlayout.mask.SkeletonMaskFactory
import com.faltenreich.skeletonlayout.mask.SkeletonShimmerDirection

open class SkeletonLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
originView: View? = null,
private val config: SkeletonConfig = SkeletonConfig.default(context)
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
originView: View? = null,
private val config: SkeletonConfig = SkeletonConfig.default(context)
) : FrameLayout(context, attrs, defStyleAttr), Skeleton, SkeletonStyle by config {

internal constructor(
originView: View,
config: SkeletonConfig
originView: View,
config: SkeletonConfig
) : this(originView.context, null, 0, originView, config)

private var mask: SkeletonMask? = null
private var isSkeleton: Boolean = false
private var isRendered: Boolean = false
private var limitToLevel: Int = Int.MAX_VALUE

init {
attrs?.let {
Expand Down Expand Up @@ -68,7 +69,6 @@ open class SkeletonLayout @JvmOverloads constructor(
}
}
}

override fun isSkeleton(): Boolean = isSkeleton

override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
Expand Down Expand Up @@ -117,8 +117,8 @@ open class SkeletonLayout @JvmOverloads constructor(
if (isSkeleton) {
if (width > 0 && height > 0) {
mask = SkeletonMaskFactory
.createMask(this, config)
.also { mask -> mask.mask(this, maskCornerRadius) }
.createMask(this, config)
.also { mask -> mask.mask(this, maskCornerRadius,limitToLevel) }
} else {
Log.e(tag(), "Failed to mask view with invalid width and height")
}
Expand All @@ -127,7 +127,12 @@ open class SkeletonLayout @JvmOverloads constructor(
Log.e(tag(), "Skipping invalidation until view is rendered")
}
}

fun getLimitToLevel():Int{
return limitToLevel
}
fun setLimitToLevel(value:Int){
this.limitToLevel = value
}
companion object {
val DEFAULT_MASK_COLOR = R.color.skeleton_mask
const val DEFAULT_MASK_CORNER_RADIUS = 8f
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,25 @@ internal abstract class SkeletonMask(protected val parent: View, @ColorInt color
canvas.drawRect(rect, paint)
}

fun mask(viewGroup: ViewGroup, maskCornerRadius: Float) {
fun mask(viewGroup: ViewGroup, maskCornerRadius: Float, offsetFromRootView:Int) {
val xferPaint = Paint().apply {
xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC)
isAntiAlias = maskCornerRadius > 0
}
mask(viewGroup, viewGroup, xferPaint, maskCornerRadius)
mask(viewGroup, viewGroup, xferPaint, maskCornerRadius,offsetFromRootView,currentLevel=0)
}

private fun mask(view: View, root: ViewGroup, paint: Paint, maskCornerRadius: Float) {
private fun mask(view: View, root: ViewGroup, paint: Paint, maskCornerRadius: Float, limitViewLevel: Int, currentLevel:Int = 0) {
(view as? ViewGroup)?.let { viewGroup ->
viewGroup.views().forEach { view -> mask(view, root, paint, maskCornerRadius) }
viewGroup.views().forEach {
if (limitViewLevel <= currentLevel){
maskView(it, root, paint, maskCornerRadius)
}
else{
mask(it, root, paint, maskCornerRadius,limitViewLevel,currentLevel+1)
}

}
} ?: maskView(view, root, paint, maskCornerRadius)
}

Expand Down