$ show koral--/android-gif-drawable
android-gif-drawable is a mature Android library for rendering animated GIFs in Views and OpenGL surfaces. It decodes GIF frames using a bundled GIFLib via JNI, providing a high-performance, battery-friendly alternative to WebView or the deprecated Movie class. The library offers a rich set of components: GifDrawable (an Animatable Drawable with full media control), GifImageView, GifImageButton, GifTextView, GifTextureView, and GifTexImage2D for OpenGL ES 2.0+. It supports multiple input sources (files, streams, byte arrays, URIs, etc.), subsampling, loop control, animation listeners, and saved state restoration. The architecture is cleanly separated into Java/Kotlin public API, native C code (with optimized ARM assembly for memset), and a sample app demonstrating various features. The codebase is well-maintained, with recent releases and active dependency updates.
The LLM identified 4 files worth highlighting for reuse:
Allows a single Drawable to be associated with multiple View callbacks, using a CopyOnWriteArrayList of weak references. This solves the problem that a Drawable normally only animates for the last View it is assigned to. The implementation is safe, handles null references, and supports both standard invalidateDrawable and View.invalidate() modes. It is a standalone class depending only on Android SDK, making it reusable in any project needing a shared drawable across multiple views.
An abstract interface defining two methods: onBoundsChange and onDraw. It decouples custom drawing transformations (e.g., rounded corners, scaling) from the GIF drawable. This allows clients to inject arbitrary drawing logic without modifying the drawable class. The interface is minimal and reusable; any Android Drawable can adopt this pattern to support custom transformations.
A concrete implementation of Transform using BitmapShader to clip the GIF bitmap to rounded corners. It handles shader creation and matrix updates on bounds change. The implementation is self-contained, using only Android graphics APIs, and can be easily extracted to provide rounded corners for any Drawable that uses a Bitmap.
A simple, thread-safe condition variable (similar to Android's internal class) that allows one thread to block until another signals a condition. It is used internally by GifTextureView to synchronize surface availability. The implementation is minimal, correct, and depends only on Java standard library. It is a reusable concurrency primitive for any Android or Java project.