# ShineButton: an Android shine-effect button library with a Jetpack Compose path

> ShineButton is an MIT-licensed Android UI library that draws a Twitter-style heart burst around a button, and the README now documents both a View-based ShineButton and a ShineButtonCompose composable. The catch is that its newest tagged release predates the Compose support it advertises.

**ChadCSong/ShineButton** — This is a UI lib for Android. Effects like shining.

- Repository: https://github.com/ChadCSong/ShineButton
- Stars: 4,193 · Forks: 540
- Language: Kotlin
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/chadcsong-shinebutton

## What ShineButton solves, and the apps it fits

A like button is a small piece of UI with an outsized job: confirm that a tap registered and make the confirmation feel good. Android's stock widgets do not do the second part. ShineButton exists to fill that gap. It is a custom view that renders a shape from a mask resource and, when checked, emits a burst of particles around the button, which the README compares to Twitter's heart animation. The repository describes it as a lightweight, customizable Android UI library, and the topics attached to it are button, custom and effects.

The audience is narrow on purpose. This is for Android developers who are already building a screen and want one interaction to carry more weight: a favourite toggle, a bookmark, a rating control. It is not a design system and it does not ship a theme. You bring the mask, the colours and the layout. The README's own credits point at fave-button for iOS as the inspiration, so the mental model is a port of an iOS interaction pattern rather than an Android-native idiom.

## How the shine effect is actually assembled

The mechanism is a masked view plus a particle system. You supply a raw PNG mask through app:siShape or setShapeResource(int), and the library uses it to define the button's silhouette. Two colours drive the resting and checked states: btn_color for the initial fill and btn_fill_color for the colour after the button is checked. The README's attribute table gives Color.GRAY and Color.BLACK as the defaults for those two.

The burst itself is parameterised rather than hard-coded. shine_count controls how many particles are drawn and defaults to 8. big_shine_color and small_shine_color set the colours of the primary and secondary particles separately. shine_distance_multiple, defaulting to 1.5f, scales how far from the button centre the particles travel, and shine_turn_angle, defaulting to 20, offsets their angle. Two durations govern timing: shine_animation_duration defaults to 1500 ms for the shine, click_animation_duration defaults to 200 ms for the click response. Setting allow_random_color to true makes the shine effects pick random colours instead of the configured ones, which is a deliberate trade of brand consistency for playfulness.

The animation timing is not written from scratch. The README credits EasingInterpolator for the smooth animation, and it credits android-shape-imageview for concepts used in the masking. Those are the two moving parts: an interpolator that shapes the motion curve, and a mask-based draw path that shapes the button.

## Installing ShineButton and wiring a first button

The README offers three distribution routes: JitPack, Maven Central and a plain Maven dependency block. JitPack is marked as recommended for the latest version. Add the JitPack repository to the root build.gradle first, then declare the dependency in the app module.

```gradle
allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}
```

The README's app-level dependency line for JitPack is com.github.ChadCSong:ShineButton:v2.0.0. The Maven Central coordinates in the same README are different: com.sackcentury:shinebutton:2.0.0. Those two strings are not interchangeable, so pick one source and stay with it.

```gradle
dependencies {
    implementation 'com.sackcentury:shinebutton:2.0.0'
}
```

The simplest first use is the XML layout. The README's example sets a 50dp square, points android:src and app:btn_color at a darker grey, sets app:btn_fill_color to #FF6666, disables random colour, and supplies the mask with app:siShape="@raw/like". Note that siShape takes a raw resource, so the mask file has to live in res/raw.

```xml
<com.sackcentury.shinebuttonlib.ShineButton
    android:id="@+id/shine_button"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:layout_centerInParent="true"
    android:src="@android:color/darker_gray"
    app:btn_color="@android:color/darker_gray"
    app:btn_fill_color="#FF6666"
    app:allow_random_color="false"
    app:siShape="@raw/like" />
```

In Java, the view needs an explicit init call with the hosting activity before it will animate correctly.

```java
ShineButton shineButton = (ShineButton) findViewById(R.id.shine_button);
shineButton.init(activity);
```

If the button sits inside a Dialog, the README states that you must call setFixDialog(dialog) so it renders correctly. That is one line, and forgetting it is the kind of bug that only shows up in a dialog flow.

## The Compose API and the release-version mismatch

The README documents a native Compose entry point called ShineButtonCompose, taking isChecked, onCheckedChange, an ImageVector shape, btnColor, btnFillColor, shineColor, shineSize and allowRandomColor. The example uses Icons.Default.Favorite as the shape, which means the Compose path does not need a raw PNG mask the way the View path does. That is a real ergonomic difference: vector icons work directly.

The problem is the version story. The README's installation section points at 2.0.0, while the repository's release list shows v0.2.0 (Fix bug.) on 2017-11-13 and v0.1.9 on 2017-07-02. No 2.0.0 release entry appears in that list. The README also lists Kotlin Migration, Jetpack Compose, Vector Support, Custom Animators, Material 3 and Performance as completed roadmap items, all checked. Treat the checked boxes as claims about the source tree rather than about a published artifact, and confirm that whatever coordinate you paste actually resolves before you build a screen around it.

A second mismatch is quieter. The repository's primary language is Kotlin, yet the usage examples for the View path are Java, and the attribute table lists Java method names. The Compose example is Kotlin. So the documentation is split across two eras of the codebase, and a Kotlin-first team will be reading Java signatures to find the setters.

## Where ShineButton is the wrong choice

The library animates a canvas. Anything that does that has a cost, and the README does not publish frame-time measurements, memory figures or device-specific behaviour, so you cannot budget from the documentation alone. On a long scrolling list where every row holds a shine button, the particle draw work multiplies with the visible rows. The README's roadmap claims canvas and allocation optimisation as done, but no numbers accompany that claim.

The masking model is the second constraint. The View path wants a raw PNG mask, and the README's XML example points siShape at @raw/like. A PNG mask is a fixed-resolution asset. If you need the same button at several sizes with crisp edges, you are managing multiple mask files or accepting scaling artefacts. The Compose path sidesteps this with ImageVector, but that only helps if you are on Compose and the artifact resolves.

Then there is the dependency question. If your product needs a component with a documented support window, a changelog you can read release by release, and a predictable upgrade cadence, this is not that component. The CHANGELOG.md file exists in the repository root, but the release list stops in 2017. For a decorative interaction on a side screen, that is acceptable. For a checkout button, it is not.

## ShineButton against fave-button and hand-rolled animators

The README itself names the closest alternative: fave-button, an iOS library by xhamr, which it credits as the inspiration. The difference is platform, not approach. fave-button targets iOS, so it is not a substitute for an Android app, but if you are building both platforms and want the same interaction on each, you are looking at two separate codebases with two separate maintenance stories rather than one shared component.

The other realistic alternative is writing the burst yourself with Android's animation APIs, or using a general-purpose animation library. That route gives you full control over the particle count, the easing and the draw path, and it removes a third-party dependency whose newest tag is from 2017. The cost is that you reimplement masking, particle placement and the interpolator wiring that ShineButton already packages. The README's credits list EasingInterpolator as a separate dependency it builds on, which hints at how much of the work is assembly rather than invention.

If your app already has a house animation library, adding ShineButton means a second animation vocabulary in the same codebase. That is a design decision, not a technical one, and the README does not take a position on it.

## Licence and the cost of staying on this dependency

ShineButton is MIT licensed, and the README points at the LICENSE file for details. MIT is permissive: it allows commercial use, modification and redistribution provided the copyright notice and permission notice are retained. The practical implication is that you can vendor the source into your own module if you need to patch it, which is worth knowing given the age of the published tags. This is a description of the licence text, not legal advice; your own counsel should review it if the dependency matters to a shipped product.

Upgrade cost is the harder number. Android's build tooling has moved on considerably since 2017, and the repository still carries a .travis.yml at its root alongside .github/, gradle/ and a Gradle wrapper. Two CI configurations in one repository usually means the older one is vestigial. If you adopt ShineButton, budget for the possibility that you are the one maintaining your fork. The last push to the repository was on 2026-07-30, so the source is not frozen, but a push is not a release, and the release list has not gained an entry since 2017-11-13.

## Conclusion

ShineButton fits Android apps that want a like or favourite button with a particle burst and are willing to pin a dependency and verify the artifact themselves, because the README's 2.0.0 coordinates and the repository's newest tag, v0.2.0 from 2017-11-13, do not line up. Teams on Compose-only stacks should confirm that ShineButtonCompose actually resolves from the chosen repository before planning around it. If you need a maintained component with a release history you can audit, look elsewhere: the last push to this repository was on 2026-07-30, but the release page has not moved in years.

## FAQ

### How do I add ShineButton to an Android project?

The README gives three routes: the JitPack repository plus com.github.ChadCSong:ShineButton:v2.0.0, or the Maven Central coordinate com.sackcentury:shinebutton:2.0.0, or an equivalent Maven dependency block with groupId com.sackcentury and artifactId shinebutton. JitPack is marked as recommended for the latest version.

### Does ShineButton work inside a Dialog?

Yes, but the README states that you must call setFixDialog(dialog) on the ShineButton instance so it renders correctly inside a Dialog.

### Can I use ShineButton with Jetpack Compose?

The README documents a ShineButtonCompose composable that takes isChecked, onCheckedChange, an ImageVector shape, btnColor, btnFillColor, shineColor, shineSize and allowRandomColor. Note that the release list shows v0.2.0 from 2017-11-13 as the newest tag, so verify the artifact resolves before relying on it.

### What Android version does ShineButton require?

The README lists Android API Level 14 or higher, described as Android 4.0 and above, as the requirement.

### What licence is ShineButton released under?

The README states it is MIT licensed and points at the LICENSE file in the repository for details.

## Sources

- [ChadCSong/ShineButton on GitHub](https://github.com/ChadCSong/ShineButton)
- [Issues](https://github.com/ChadCSong/ShineButton/issues)
- [License: MIT](https://github.com/ChadCSong/ShineButton/blob/master/LICENSE)
- [README](https://github.com/ChadCSong/ShineButton/blob/master/README.md)
- [Releases](https://github.com/ChadCSong/ShineButton/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/chadcsong-shinebutton
