Skeleton-Bones: Can't get the examples working

First thanks for what seems like a great library with great technical solution to the problem and good documentation as well.

But I can’t get it to work, so I have a few questions/bug findings:

  1. We are not using databinding, but I there seems also to be a great api for that case. But trying to use the examples only gives me a black box, no animation at all. I have tried to set almost every property without any animation as a result. What is the problem do you think?
    SkeletonDrawable.create(this).apply {
        this.getProps().apply {
            this.enabled = true
            this.allowSavedState = true
            this.shimmerRayProperties.apply {
                this.shimmerRayThickness = 10.dp
                this.shimmerRayTilt = 0.3f
            }
        }
    }

    SkeletonDrawable.create(this)
        .build()
        .setEnabled(true)
        .setAllowSavedState(true)
        .withShimmerBuilder {
            setThickness(10.dp)
            setTilt(0.3f)
            setAnimationDuration(300L)
        }
        .setCornerRadii(3f)
        .setColor(MutableColor(appCtx.getColor(R.color.green)))
        .withBoneBuilder(generateId()) {
            setColor(MutableColor(appCtx.getColor(R.color.lemon)))
            setMaxThickness(12.dp)
            setMinThickness(10.dp)
            setCornerRadii(CornerRadii(3f))
            setEnabled(true)
            setTransitionDuration(300L)
        }
        .setUseStateTransition(true)
  1. There are quite a few properties from “Example Usages 1” that does not seems to be accessible from the other approaches. Some of them seems important, is I just me that can’t find them?
app:skeletonGenerateBones
app:skeletonAnimateRestoredBounds
  1. When creating a SkeletonDrawable for a ViewGroup, how then to select which child views that should be skeletonable?
  2. Is it possible to make a View skeletonable without going through it parent, or is the same case as 3. question?
  3. In the readme setCornerRadius() should be changed to setCornerRadii()

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Comments: 27 (15 by maintainers)

Commits related to this issue

Most upvoted comments

@mortenholmgaard I will try to find sometime to address, I have unfortunately been very busy and unable to put time into the library. I have a feeling that I will soon get the chance again to work on it more consistently. I am sorry for any inconvenience this may cause. I will also keep you updated with any work or update that have been made

Hey @mortenholmgaard sorry I have not addressed this yet, I have been busy with my day job and family and I only have the ability to work on this on the late evenings. I believe I will have a chance work on this library and address the issues before the end of the week 🙏 . Ill ping you as soon as I have an update. Sorry for any inconvenience

@EudyContreras I have just made an example of the problem in a pull request including a video. It should make it simplere to figure out the problem - I hope you can find time to take a look at it 😃

Hey @mortenholmgaard thank you for the example, have not been able to work on the lib lately but as soon as I get a chance I will look at your example and start making the improvements 😄

@EudyContreras I have just made an example of the problem in a pull request including a video. It should make it simplere to figure out the problem - I hope you can find time to take a look at it 😃

@EudyContreras Sounds good - looking forward to hear from you with a fix for the current problem 😃

Okay first of all conceptually for me a skeleton is bound to a View. That meaning that i ideally just see it as simple as enable og disabling a skeleton for a View. And ideally it is also possible to handle a skeleton for a viewGroup like it was a View (single skeleton filling the ViewGroup) or handling the ViewGroup as an easy entry for enabling/disabling all skeleton enabled views in it. So conceptually for me it is all about the individual View.

Ok so basically when I designed the library I made it view-binding first, meaning that it would be easiest to use out of the box with view binding and controlled by a single boolean value which through data-binding would determine when the skeletons would be disposed/disappear. The other principle was the single use and dispose principle. Usually in the common scenario I designed for was like this:

  • The layout is is shown with skeleton drawable overlaying
  • The data loads and the skeletons become disabled because the data is now available
  • The skeleton drawable is then disposed and the original foreground of the layout is restored

This pattern was used in order to respect the fact that the layout may already be intended to have some other foreground drawable that should not be completely replaced by the skeleton drawables. I will improve views to have foreground skeleton drawables that can be enable and disabled easily.

Skeleton drawable are built using a view, this makes it less straight forward to use the drawable for other views, this will change in the future. I aim to provide the most flexibility so i will make improvements when i have time 🙏 .

I am not using Coroutines and ViewModels yet so it is not that simple for me to just reuse the sample directly.

I ll make more demos without coroutines and ViewModels

But how come this will not work if it is possible: itemView.ItemBOuterText.enableSkeletonLoading()

When creating a skeleton drawable for a ViewGroup we create only one drawable with virtual bones that overlay the children of the ViewGroup, no drawables are created for the children. This means that if the skeleton drawable is disabled/disposed for a ViewGroup it will not be possible to interact with it anymore, I will try to find a way around this

I will look a little closer into this issues and Ill get back to you 🙌

Great work!! It is pretty close to be working perfectly for me.

Awesome to hear 🙌

shimmerRayProperties is not really possible to use as ShimmerRayProperties only has an internal constructor. I see there is a similar pattern with the other builders. What is the reason and purpose of that way of handling it?

I will be fixing this on the next release 🙏 . It does not make sense for those to be internal…

In relation to getParentSkeletonDrawable() I can see that it is internal, so I can’t use that one currently. internal fun View.getParentSkeletonDrawable(): SkeletonDrawable? { … }

It is public in the last release.

fun ViewGroup.getSkeletonDrawable(): SkeletonDrawable? { … } This could be related to the reuse in recyclerView problems I currectly have but can’t really figure it out without eliminating this cause.

Those will be added on the next release 🙌

In addition to the points above I am thinking of adding a property to the drawables which will make it easier to reuse them. Something like

fun resetForReuse()

Thanks for your feedback 😃

  1. That example works! But this is a problem with margins. I the demo-3 example when adding start margin to ItemBImage
    <ImageView
        android:id="@+id/ItemBImage"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_marginStart="30dp"
        ...

then the skeleton width will only be 30dp and not the expected 60dp.

  1. Okay

  2. and 4. Sounds good - we will be awaiting that 👍 We have cells where multiple things are loading async and there by different parts of the data is appearing one by one. What would be most ideal is also that it is possible in both xml and Builder to se if a view is skeletonable - I don’t know if that is possible currently. Regarding withBoneBuilder it might be as good to take the view directly because with view binding we have access to that anyway so if that is possible and possibly also makes it faster, that could also be a option to add.

I also looked at the stop skeletons issue https://github.com/EudyContreras/Skeleton-Bones/issues/19 but didn’t find any good solutions for I using the code, except keeping a reference to the Builder. I would love if it was possible just to have an extension metod on views that is could call to enable/disable skeletons for a view og viewGroup.

Also a different input could be the I don’t know if it would improve performance(not that I have seen any problems yet) to have a general reusable builder, so that you could easy reused the same skeletons thought out you app - which will be what you want most of the time. So the skeleton could be added by a property in the view xml or code, perphaps you have a few different once like you do with style for a type of elements.