Synchronized Frame Animation Across Multiple Android Views (Mirror Frame Animation)
This article explains the concept of "same‑frequency same‑frame" animation, analyzes the limitations of existing animation engines, and presents a Drawable‑based projection technique with code examples to synchronize animation frames across multiple Android views while reducing memory and CPU overhead.
The article introduces the notion of "same‑frequency same‑frame" animation, where identical frames are displayed simultaneously on multiple views at the same frequency, and outlines its advantages for symmetric visual effects.
It reviews common animation engines (libPag, Lottie, APNG, GIF, SVGA, etc.), highlighting their memory, decoding, and compatibility drawbacks, especially on low‑end devices.
To overcome these issues, the author proposes a projection approach using a custom Drawable wrapper that can be shared across views. The wrapper scales the original drawable to each target view via a Matrix , preserving alpha and color filters.
Key implementation details include:
Reference to Glide's FixedSizeDrawable for scaling logic.
Definition of AnimationDrawableWrapper extending Drawable , handling drawing, alpha, color filter, and matrix transformations.
Implementation of MirrorFrameAnimation that manages a list of wrappers, synchronizes updates via Drawable.Callback , and schedules frames using Choreographer .
Utility methods for starting, stopping, querying frame count, duration, and cloning drawables.
Code snippets (wrapped in ... ) illustrate the core classes and usage:
public class MirrorFrameAnimation implements Drawable.Callback, Choreographer.FrameCallback {
private final Drawable drawable;
private final int drawableWidth;
private final int drawableHeight;
private List<WeakReference<AnimationDrawableWrapper>> drawableList = new ArrayList<>();
private Choreographer choreographer;
private Runnable scheduleTask;
// Constructors, start/stop, frame queries, syncDrawable, etc.
} public static class AnimationDrawableWrapper extends Drawable {
private final Drawable animationDrawable;
private final Matrix matrix = new Matrix();
private final RectF wrappedRect;
private final RectF drawableBounds;
private final Matrix.ScaleToFit scaleToFit;
private int alpha = 255;
private ColorFilter colorFilter;
// draw(), setAlpha(), setColorFilter(), getOpacity() implementations
}Usage example shows creating a MirrorFrameAnimation instance, synchronizing it with six ImageView objects using different Matrix.ScaleToFit options, and controlling playback via start/stop buttons.
The solution is applicable to scenarios requiring synchronized image execution, such as symmetric fire or confetti effects in TV shows or chat avatars, offering reduced thread count and memory consumption.
In summary, the Drawable‑based projection method provides an efficient way to achieve synchronized frame animations on Android, especially on low‑end devices where traditional engines may cause performance issues.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.