Android library for rendering Adobe After Effects animations exported as JSON through Bodymovin with native performance and extensive customization options.
—
Factory methods and async operations for loading Lottie animations from various sources including assets, raw resources, URLs, and streams. All loading operations return LottieTask instances for async handling with built-in caching support.
Factory class providing static methods for loading animations from different sources. All methods return LottieTask<LottieComposition> for async handling.
/**
* Factory for creating LottieComposition instances from various sources
*/
public class LottieCompositionFactory {
// Asset loading
public static LottieTask<LottieComposition> fromAsset(Context context, String fileName);
public static LottieTask<LottieComposition> fromAsset(Context context, String fileName, String cacheKey);
// Raw resource loading
public static LottieTask<LottieComposition> fromRawRes(Context context, @RawRes int rawRes);
public static LottieTask<LottieComposition> fromRawRes(Context context, @RawRes int rawRes, String cacheKey);
// URL loading with caching
public static LottieTask<LottieComposition> fromUrl(Context context, String url);
public static LottieTask<LottieComposition> fromUrl(Context context, String url, String cacheKey);
// JSON string loading
public static LottieTask<LottieComposition> fromJsonString(String json, String cacheKey);
public static LottieTask<LottieComposition> fromJsonInputStream(InputStream stream, String cacheKey);
public static LottieTask<LottieComposition> fromJsonReader(JsonReader reader, String cacheKey);
public static LottieTask<LottieComposition> fromJson(JSONObject json, String cacheKey);
// ZIP file loading (for animations with images)
public static LottieTask<LottieComposition> fromZipStream(ZipInputStream inputStream, String cacheKey);
public static LottieTask<LottieComposition> fromZipStreamSync(ZipInputStream inputStream, String cacheKey);
// Synchronous loading methods (use with caution on main thread)
public static LottieResult<LottieComposition> fromAssetSync(Context context, String fileName);
public static LottieResult<LottieComposition> fromAssetSync(Context context, String fileName, String cacheKey);
public static LottieResult<LottieComposition> fromRawResSync(Context context, @RawRes int rawRes);
public static LottieResult<LottieComposition> fromRawResSync(Context context, @RawRes int rawRes, String cacheKey);
public static LottieResult<LottieComposition> fromUrlSync(Context context, String url);
public static LottieResult<LottieComposition> fromUrlSync(Context context, String url, String cacheKey);
public static LottieResult<LottieComposition> fromJsonStringSync(String json, String cacheKey);
public static LottieResult<LottieComposition> fromJsonInputStreamSync(InputStream stream, String cacheKey);
public static LottieResult<LottieComposition> fromJsonSync(JSONObject json, String cacheKey);
public static LottieResult<LottieComposition> fromJsonReaderSync(JsonReader reader, String cacheKey);
// Cache management
public static void setMaxCacheSize(int size);
public static void clearCache(Context context);
}Usage Examples:
// Load from assets
LottieCompositionFactory.fromAsset(context, "animation.json")
.addListener(composition -> {
animationView.setComposition(composition);
animationView.playAnimation();
})
.addFailureListener(throwable -> {
Log.e("Lottie", "Failed to load animation", throwable);
});
// Load from raw resources
LottieCompositionFactory.fromRawRes(context, R.raw.loading_animation)
.addListener(animationView::setComposition);
// Load from URL with custom cache key
LottieCompositionFactory.fromUrl(context, "https://example.com/animation.json", "custom_key")
.addListener(composition -> {
drawable.setComposition(composition);
drawable.playAnimation();
});
// Load from JSON string
String animationJson = "{ ... }"; // Lottie JSON
LottieCompositionFactory.fromJsonString(animationJson, "inline_animation")
.addListener(composition -> {
// Use composition
});
// Load from input stream
try (InputStream stream = new FileInputStream(animationFile)) {
LottieCompositionFactory.fromJsonInputStream(stream, "file_animation")
.addListener(composition -> {
// Use composition
});
}
// Load ZIP file (with images)
try (ZipInputStream zipStream = new ZipInputStream(new FileInputStream(zipFile))) {
LottieCompositionFactory.fromZipStream(zipStream, "zip_animation")
.addListener(composition -> {
// Use composition
});
}
// Synchronous loading (background thread only)
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {
LottieResult<LottieComposition> result =
LottieCompositionFactory.fromAssetSync(context, "animation.json");
if (result.getValue() != null) {
// Success - switch to main thread to use composition
Handler mainHandler = new Handler(Looper.getMainLooper());
mainHandler.post(() -> {
animationView.setComposition(result.getValue());
});
} else {
Log.e("Lottie", "Failed to load", result.getException());
}
});
// Cache management
LottieCompositionFactory.setMaxCacheSize(50); // Increase cache size
LottieCompositionFactory.clearCache(context); // Clear all cached animationsImmutable composition model representing a parsed After Effects animation. Contains all animation data including layers, assets, timing information, and metadata.
/**
* Immutable composition model representing parsed After Effects animation
*/
public class LottieComposition {
// Bounds and dimensions
public Rect getBounds();
// Timing information
public float getDuration(); // Duration in milliseconds
public float getDurationAsSeconds(); // Duration in seconds
public float getStartFrame();
public float getEndFrame();
public float getFrameRate();
public float getDurationFrames(); // Duration in frames
// Animation structure
public List<Layer> getLayers();
public LongSparseArray<Layer> getLayerMap();
public Map<String, List<Layer>> getPrecomps();
// Assets
public Map<String, LottieImageAsset> getImages();
public boolean hasImages();
public Map<String, Font> getFonts();
public SparseArrayCompat<FontCharacter> getCharacters();
// Markers
public List<Marker> getMarkers();
public Marker getMarker(String markerName);
// Performance characteristics
public boolean hasDashPattern();
public int getMaskAndMatteCount();
// Debugging and analysis
public Set<String> getWarnings();
public PerformanceTracker getPerformanceTracker();
// Internal methods (library use)
@RestrictTo(RestrictTo.Scope.LIBRARY)
public void addWarning(String warning);
@RestrictTo(RestrictTo.Scope.LIBRARY)
public void setHasDashPattern(boolean hasDashPattern);
@RestrictTo(RestrictTo.Scope.LIBRARY)
public void incrementMatteOrMaskCount(int amount);
}Usage Examples:
// Analyze composition
LottieCompositionFactory.fromAsset(context, "complex_animation.json")
.addListener(composition -> {
Log.d("Lottie", "Duration: " + composition.getDurationAsSeconds() + "s");
Log.d("Lottie", "Frame rate: " + composition.getFrameRate() + " fps");
Log.d("Lottie", "Has images: " + composition.hasImages());
Log.d("Lottie", "Mask/matte count: " + composition.getMaskAndMatteCount());
// Check for markers
List<Marker> markers = composition.getMarkers();
for (Marker marker : markers) {
Log.d("Lottie", "Marker: " + marker.getName() +
" at frame " + marker.getStartFrame());
}
// Check warnings
Set<String> warnings = composition.getWarnings();
if (!warnings.isEmpty()) {
Log.w("Lottie", "Animation warnings: " + warnings);
}
});
// Use composition bounds for layout
composition.getBounds(); // Returns Rect with animation bounds
int width = composition.getBounds().width();
int height = composition.getBounds().height();
// Performance analysis
PerformanceTracker tracker = composition.getPerformanceTracker();
tracker.setEnabled(true);
// ... after animation plays
Map<String, Float> renderTimes = tracker.getSortedRenderTimes();Async task wrapper for handling loading operations with success and failure callbacks. Provides chainable API for handling results.
/**
* Async task helper for loading operations
*/
public class LottieTask<T> {
// Result listeners
public LottieTask<T> addListener(LottieListener<T> listener);
public LottieTask<T> removeListener(LottieListener<T> listener);
public LottieTask<T> addFailureListener(LottieListener<Throwable> listener);
public LottieTask<T> removeFailureListener(LottieListener<Throwable> listener);
// Static executor configuration
public static Executor EXECUTOR; // Default: cached thread pool
}Usage Examples:
// Chaining listeners
LottieCompositionFactory.fromAsset(context, "animation.json")
.addListener(composition -> {
// Success callback
animationView.setComposition(composition);
animationView.playAnimation();
})
.addFailureListener(throwable -> {
// Error callback
Log.e("Lottie", "Failed to load animation", throwable);
showErrorState();
})
.addListener(composition -> {
// Additional success callback
enableAnimationControls();
});
// Remove listeners
LottieListener<LottieComposition> listener = composition -> { /* ... */ };
LottieTask<LottieComposition> task = LottieCompositionFactory.fromAsset(context, "animation.json");
task.addListener(listener);
// Later...
task.removeListener(listener);
// Custom executor
LottieTask.EXECUTOR = Executors.newFixedThreadPool(2);Result wrapper containing either a success value or an exception. Used by synchronous loading methods.
/**
* Result wrapper for sync operations
*/
public class LottieResult<V> {
public LottieResult(V value);
public LottieResult(Throwable exception);
public V getValue();
public Throwable getException();
@Override
public boolean equals(Object o);
@Override
public int hashCode();
}Usage Examples:
// Check result
LottieResult<LottieComposition> result =
LottieCompositionFactory.fromAssetSync(context, "animation.json");
if (result.getValue() != null) {
LottieComposition composition = result.getValue();
// Use composition
} else if (result.getException() != null) {
Throwable error = result.getException();
Log.e("Lottie", "Load failed", error);
}public interface LottieNetworkFetcher {
LottieResult<LottieComposition> fetchSync(String url, String cacheKey);
}
public interface LottieNetworkCacheProvider {
File getCacheDir();
}
public interface LottieFetchResult {
boolean isSuccessful();
InputStream bodyByteStream();
String contentType();
}
public class DefaultLottieNetworkFetcher implements LottieNetworkFetcher {
public DefaultLottieNetworkFetcher();
public LottieResult<LottieComposition> fetchSync(String url, String cacheKey);
}Install with Tessl CLI
npx tessl i tessl/maven-com-airbnb-android--lottie