A shimmer library for Android's Jetpack Compose.

Overview

Shimmer for Jetpack Compose

A library which offers a shimmering effect for Android's Jetpack Compose.

It was developed in need for a shimmer effect that traverses across the whole screen, bringing only a certain subset of child views to shine.

Download

repositories {
  mavenCentral()
}

dependencies {
  implementation 'com.valentinilk.shimmer:compose-shimmer:1.0.0'
}

Usage

The library provides a simple shimmer() modifier which can be applied like any other modifier in Compose as well.

As usual, the order of the modifiers matters. Every visual defined after the modifier will be affected by the shimmer. This includes child views and other modifiers as for example background():

Box(
  modifier = Modifier
    .size(128.dp)
    .background(Color.Blue)
    .shimmer(),
  contentAlignment = Alignment.Center
) {
  Box(
    modifier = Modifier
      .size(64.dp)
      .background(Color.Red)
  )
}

Box(
  modifier = Modifier
    .size(128.dp)
    .shimmer()
    .background(Color.Blue),
  contentAlignment = Alignment.Center
) {
  Box(
    modifier = Modifier
      .size(64.dp)
      .background(Color.Red)
  )
}

Theming

The library includes a ShimmerTheme which can be provided as a local composition. So overwriting the shimmer's default theme for the whole application is possible as usual:

val yourShimmerTheme = defaultShimmerTheme.copy(...)
CompositionLocalProvider(
  LocalShimmerTheme provides yourShimmerTheme
) {
  ...
}

The theme offers a few simple configurations like the shimmer's rotation or width. Additionally few unabstracted objects like an AnimationSpec or BlendMode are exposed. While this violates the principales of information hiding it allows for some great customizations.

For further information have a look at documentation in data class itself and have a look at the ThemingSamples in the sample app.

Advanced Usage

The default shimmer() modifier creates a shimmering effect that will traverse over an area that is equal to the view's position and size. While this looks great for most cases, it just doesn't look as satisfiying for cases where the shimmer has to be applied to multiple views:

Due to the differences in sizes, all three shimmers have a different velocitiy, which doesn't look as calm as it should be. Even having in fact three different and independent shimmerings doesn't look as clean as it could.

That's why the library offers different options for the effect's boundaries:

val shimmerInstance = rememberShimmer(shimmerBounds = ShimmerBounds.XXX)
Box(modifier = Modifier.shimmer(shimmerInstance))

ShimmerBounds.Window

One option is to use the boundaries of the current window. This will create a shimmer that travels over the whole window, while affecting only the views (and child views) which have the shimmer modifier attached.

Column {
  val shimmerInstance = rememberShimmer(shimmerBounds = ShimmerBounds.Window)
  Text("Shimmering Text", modifier = Modifier.shimmer(shimmerInstance))
  Text("Non-shimmering Text")
  Text("Shimmering Text", modifier = Modifier.shimmer(shimmerInstance))
}

ShimmerBounds.Custom

By using the Window option one imperfection remains, which can be a problem if the content is for example scrollable. Attaching the effect to the window means its position is fixed. So while the shimmer is traversing over the content, the content itself might be moved relative to the shimmer. Depending on the theme this effect might be more or less visible.

That's where the ShimmerBounds.Custom option comes into play. By using it the shimmer and its content will not be drawn until the bounds are set manually by using the updateBounds method on the Shimmer.

val shimmerInstance = rememberShimmer(ShimmerBounds.Custom)
Column(
  modifier = Modifier
    .fillMaxSize()
    .verticalScroll(rememberScrollState())
    .onGloballyPositioned { layoutCoordinates ->
      // Util function included in the library
      val position = layoutCoordinates.unclippedBoundsInWindow()
      shimmerInstance.updateBounds(position)
    },
) {
  Text("Shimmering Text", modifier = Modifier.shimmer(shimmerInstance))
  Text("Non-shimmering Text")
  Text("Shimmering Text", modifier = Modifier.shimmer(shimmerInstance))
}

Updating the bounds will not trigger a recomposition.

License

Copyright 2021 Valentin Ilk

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • custom shimmer ignores provided theme

    custom shimmer ignores provided theme

    Hello there.

    I was expecting this code to sync the animation between all the children with the .shimmer modifier but using this custom shimmer will override the ShimmerTheme provided by the CompositionLocalProvider

    val shimmer =  rememberShimmer(shimmerBounds = ShimmerBounds.Window)
    
    CompositionLocalProvider(
        LocalShimmerTheme provides shimmerTheme
     ) {
         Card(
            modifier = modifier
                .shimmer(shimmer),
            elevation = elevation,
            backgroundColor = color,
        ) {}
    }
    

    What ends up happening is all the views with the custom shimmer will ignore my custom theme

    Would appreciate your help on this issue

    PS: Thank you for the library, its very nice.

    opened by FernandoCCNunes 2
  • Is there a way control the interval between the animations?

    Is there a way control the interval between the animations?

    Hi. First of all, congratulations for the library. It's very useful. Could you tell me if there's a way to control the interval between the animation? And/Or set the animation's duration?

    I'm using in my app and (fortunately) the backend respond very quickly so very often it's not possible to see the animation even once...

    Thanks in advance.

    opened by nglauber 2
  • enable disable shimmer easily

    enable disable shimmer easily

    Hi!

    I want to use this library, and from my use case would be great if I can just say the to shimmer Modifier if should be enabled or not.

    I created a sample screen for the visibility use case I am proposing.

    Please, let me know if this make sense for you and if you have comments, they will be really wellcome!

    shimmer_visibility !

    opened by matiaslev 1
  • Start and stop shimmering

    Start and stop shimmering

    Is it possible to start and stop the shimmering? I have a "ScannerButton" and when isScanning = true, the shimmer effect should start otherwise the button is non-shimmering.

    Would it make sense to implement such a behavior or should I just swap the composable at the right time, e.g. when isScanning = true, then show shimmering version of button and when false show non-shimmering version. What do you think?

    opened by WebTiger89 1
  • Simmer works on android 21 too

    Simmer works on android 21 too

    Adding a movie to prove. The tooling are not important for the library. https://user-images.githubusercontent.com/629491/138448290-f439b4f0-9c9e-402e-b7a1-594c906b3133.mov

    opened by mariopce 1
  • Test takes a very long time to return result

    Test takes a very long time to return result

    Hey Valentin! I'm implementing unit tests for my Composables that use your shimmer, but they are not passing within a reasonable time. When Modifier.shimmer() is called, unit tests seems to continue running for a while, then eventually finishes after a very long time.

    Given the following Activity:

    class ShimmerActivity : AppCompatActivity()  {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContent {
                Box(
                    modifier = Modifier
                        .fillMaxSize()
                        .shimmer()
                        .background(Color.White)
                )
            }
        }
    }
    

    And the following test :

    @RunWith(RobolectricTestRunner::class)
    class ShimmerActivityTest {
    
        @Test
        fun shimmer_activity_test() {
            launchActivity<ShimmerActivity>().onActivity {
                assertTrue(true)
            }
        }
    }
    

    The test only passes after more than 2 hours.

    image

    But when //.shimmer() is commented out, then the test passes as expected after a few seconds.

    image

    opened by hoboris 1
Releases(v1.0.3)
Owner
Valentin Ilk
Valentin Ilk
Jetpack Compose Boids | Flocking Insect 🐜. bird or Fish simulation using Jetpack Compose Desktop 🚀, using Canvas API 🎨

?? ?? ?? Compose flocking Ants(boids) ?? ?? ?? Jetpack compose Boids | Flocking Insect. bird or Fish simulation using Jetpack Compose Desktop ?? , usi

Chetan Gupta 38 Sep 25, 2022
A collection of animations, compositions, UIs using Jetpack Compose. You can say Jetpack Compose cookbook or play-ground if you want!

Why Not Compose! A collection of animations, compositions, UIs using Jetpack Compose. You can say Jetpack Compose cookbook or play-ground if you want!

Md. Mahmudul Hasan Shohag 186 Jan 1, 2023
Learn Jetpack Compose for Android by Examples. Learn how to use Jetpack Compose for Android App Development. Android’s modern toolkit for building native UI.

Learn Jetpack Compose for Android by Examples. Learn how to use Jetpack Compose for Android App Development. Android’s modern toolkit for building native UI.

MindOrks 382 Jan 5, 2023
This is a sample app(For beginners - App #2) built using Jetpack Compose. It demonstrates the concept of State Hoisting in Jetpack Compose.

JetBMICalculator This is a sample app(For beginners - App #2) built using Jetpack Compose. It demonstrates the concept of State Hoisting in Jetpack Co

BHAVNA THACKER 3 Dec 31, 2022
Jetpack-Compose-Demo - Instagram Profile UI using Jetpack Compose

Jetpack-Compose-Demo Instagram Profile UI using Jetpack Compose

omar 1 Aug 11, 2022
Jetpack-compose-animations-examples - Cool animations implemented with Jetpack compose

Jetpack-compose-animations-examples This repository consists of 4 animations: St

Canopas Software 180 Jan 2, 2023
Compose-navigation - Set of utils to help with integrating Jetpack Compose and Jetpack's Navigation

Jetpack Compose Navigation Set of utils to help with integrating Jetpack Compose

Adam Kobus 5 Apr 5, 2022
Jetpack-compose-uis - A collection of some UIs using Jetpack Compose. built using Katalog

Jetpack Compose UIs This is a collection of some UIs using Jetpack Compose. It i

Mori Atsushi 3 Dec 15, 2022
A simple authentication application using Jetpack compose to illustrate signin and sign up using Mvvm, Kotlin and jetpack compose

Authentication A simple authentication application using Jetpack compose to illustrate signin and sign up using Mvvm, Kotlin and jetpack compose Scree

Felix Kariuki 5 Dec 29, 2022
A Kotlin library to use Jetpack Compose in Android and iOS. Allow to write UI for both in Kotin. Still experimental as many compose features are not yet available.

Multiplatform Compose A Kotlin library to use Jetpack Compose in Android and iOS. Allow to write UI for both in Kotin. Still experimental as many comp

Clément Beffa 548 Jan 7, 2023
Compose-Ratingbar-library - A simple implementation for rating bar in Jetpack Compose

Compose-Ratingbar-library - A simple implementation for rating bar in Jetpack Compose

Mahmoud Hussein 14 Dec 21, 2022
Compose Curved-Scroll is an Android Jetpack Compose library made with ❤️

Compose-Curved-Scroll-library Compose Curved-Scroll is an Android Jetpack Compos

mohamed tamer 23 Aug 24, 2022
Android.compose.squircle - Android LightWeight Squircle Library for JetPack Compose

Android LightWeight Squircle Library for JetPack Compose Usage Based on Compose

Quang Nguyen 9 Jul 5, 2022
Compose-html - An Android library which provides HTML support for Jetpack Compose texts

HtmlCompose An Android library which provides HTML support for Jetpack Compose t

iRewardHealth 43 Dec 29, 2022
An application that i developed with a aim of learning Jetpack compose and many other jetpack libraries

An application that i developed with a aim of learning Jetpack compose and many other jetpack libraries, The application make use of jikan Api which displays a list of animations,there more details and even trailers of the animations.

Odhiambo Brandy 10 Nov 23, 2022
Lightweight library to tweak the fling behaviour in Android. This library is only compatible with Jetpack-Compose.

Flinger (Only compatible with compose) What is Flinger? Flinger is a plugin that is made on top of jetpack compose that will help the developer to twe

Joseph James 73 Dec 24, 2022
K5-compose is a sketchy port of p5.js for Jetpack Compose

k5-compose k5-compose is a sketchy port of P5.js for Jetpack Compose Desktop. This library provides you a playground to play with your sketches so you

Nikhil Chaudhari 176 Nov 22, 2022
Jetpack Compose based project, used to stress-testing compose features / integrations and explore non-trivial functionality

Project containing Jetpack Compose samples For pagination & network images it uses CATAAS. Known issues Navigation-Compose Issue with fast tapping on

Denis Rudenko 59 Dec 14, 2022
Pokedex Compose is an independent re-write of a demo application by the name of Pokedex, but written in jetpack compose.

Pokedex Compose Pokedex Compose is an independent re-write of a similar project by the name of Pokedex. I am recreating the UI but I am doing it using

Jose Patino 4 May 1, 2022