Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.createSkeleton() extension function replaces view but does not copy ids, which makes it incompatible with ContraintLayout #47

Open
Orbyt opened this issue Jul 10, 2024 · 0 comments

Comments

@Orbyt
Copy link

Orbyt commented Jul 10, 2024

Thank you for your great work on this library. I've been looking for a skeleton/shimmer loader library for some time, though many are unfortunately deprecated and unmaintained.

I have a standard Fragment with a layout using a ContraintLayout as it's root ViewGroup. As I don't wish to litter layouts by wrapping everything in a <com.faltenreich.skeletonlayout.SkeletonLayout />, I've opted to create the loading effect programmatically.

Your documentation notes the following:

// or create a new SkeletonLayout from a given View
skeleton = view.createSkeleton()

Here's the source for that extension function:

@JvmOverloads
fun View.createSkeleton(
    config: SkeletonConfig = SkeletonConfig.default(context)
): Skeleton {
    // If this View already has a parent, we need to replace it with the SkeletonLayout
    val parent = (parent as? ViewGroup)
    val index = parent?.indexOfChild(this) ?: 0
    val params = layoutParams

    parent?.removeView(this)

    val skeleton = SkeletonLayout(this, config)

    if (params != null) {
        skeleton.layoutParams = params
    }
    parent?.addView(skeleton, index)

    return skeleton
}

Consider the given view is a TextView in a ConstraintLayout, such as a header text for a screen. Other Views within that ConstraintLayout likely reference the TextView by id to form their layout contraints.

When the createSkeleton function is run, the original view is replaced, and though the LayoutParams are copied, other aspects of the original View, like the id, are not. This breaks the original ConstraintLayout, as any views referencing that original id are now referencing an id of a View that is no longer in the layout.

I believe copying the original id sort of works:

val id = textView.id
val skeleton = textView.createSkeleton()
(skeleton as FrameLayout).id = id

However, I'm unsure if that's the correct way to resolve the problem.

Unfortunately, many layouts in the app I am working on a quite dynamic, so creating a skeleton/shimmer loader with the root ViewGroup is difficult, as many parts of the layout are not created until data is loaded. Any insight into how to best handle these problems is appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant