Aghajari / AXrLottie

AXrLottie (Android) Renders animations and vectors exported in the bodymovin JSON format. (Using rLottie)
Apache License 2.0
147 stars 26 forks source link
bodymovin lottie lottie-android lottie-animation rlottie

AXrLottie Renders animations
and vectors exported in the bodymovin JSON format
GitHubReleases

LCoders | AmirHosseinAghajari
picker [![Platform](https://img.shields.io/badge/platform-android-green.svg)](http://developer.android.com/index.html) [![API](https://img.shields.io/badge/API-16%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=16) [![Maven Central](https://img.shields.io/maven-central/v/io.github.aghajari/AXrLottie.svg?label=Maven%20Central)](https://search.maven.org/artifact/io.github.aghajari/AXrLottie/1.4.0/aar) [![Join the chat at https://gitter.im/Aghajari/community](https://badges.gitter.im/Aghajari/community.svg)](https://gitter.im/Aghajari/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

What is lottie?

Lottie loads and renders animations and vectors exported in the bodymovin JSON format. Bodymovin JSON can be created and exported from After Effects with bodymovin, Sketch with Lottie Sketch Export, and from Haiku.

For the first time, designers can create and ship beautiful animations without an engineer painstakingly recreating it by hand. Since the animation is backed by > JSON they are extremely small in size but can be large in complexity!

What is rlottie?

rlottie is a platform independent standalone c++ library for rendering vector based animations and art in realtime.

What is AXrLottie?

AXrLottie includes rlottie into Android. Easy A!

Lottie Examples

Screenshot

Table of Contents

Changelogs

1.4.0 :

Other versions changelog

Installation

AXrLottie is available in the mavenCentral(), so you just need to add it as a dependency (Module gradle)

Gradle

implementation 'io.github.aghajari:AXrLottie:1.4.0'

Maven

<dependency>
  <groupId>io.github.aghajari</groupId>
  <artifactId>AXrLottie</artifactId>
  <version>1.4.0</version>
  <type>pom</type>
</dependency>

Usage

Let's START! :smiley:

Install AXrLottie

First step, you should initialize AXrLottie

AXrLottie.init(this);

Basic Usage

Create an AXrLottieImageView in your layout.

<com.aghajari.rlottie.AXrLottieImageView
        android:id="@+id/lottie_view"
        android:layout_width="180dp"
        android:layout_height="180dp"
        android:layout_gravity="center"/>

Now you just need to load your lottie Animation

lottieView.setLottieDrawable(AXrLottieDrawable.fromAssets(this,fileName)
                .setSize(width,height)
                .build());
lottieView.playAnimation();

you can load lottie file from following sources :

lottie will cache animations/files by default. you can disable cache in AXrLottieDrawable Builder

Output

Back to contents

LayerProperty

To update a property at runtime, you need 3 things:

  1. KeyPath
  2. AXrLottieProperty
  3. setLayerProperty(KeyPath, AXrLottieProperty)
lottieDrawable.setLayerProperty("**" /**KeyPath*/, AXrLottieProperty.fillColor(color) /**AXrLottieProperty*/);

Output

KeyPath

A KeyPath is used to target a specific content or a set of contents that will be updated. A KeyPath is specified by a list of strings that correspond to the hierarchy of After Effects contents in the original animation. KeyPaths can include the specific name of the contents or wildcards:

Keypath should contains object names separated by (.) and can handle globe(**) or wildchar(*).

Properties

DynamicProperties

Since v1.0.6 you can set dynamic properties to a layer!

Example :

lottieDrawable.setLayerProperty("**" /**KeyPath*/,
        AXrLottieProperty.dynamicFillColor(new AXrLottieProperty.DynamicProperty<Integer>() {
            @Override
            public Integer getValue(int frame) {
                if (frame > 40)
                    return Color.RED;
                else
                    return Color.BLUE;
            }
        }));

Back to contents

Layers

AXrLottieLayerInfo contains Layer's name,type,inFrame and outFrame.

for (AXrLottieLayerInfo layerInfo : lottieDrawable.getLayers()) {
    Log.i("AXrLottie", layerInfo.toString());
}

Back to contents

Markers

Markers exported form AE are used to describe a segment of an animation {comment/tag , startFrame, endFrame} Marker can be use to divide a resource in to separate animations by tagging the segment with comment string , start frame and duration of that segment.

More...

AXrLottieMarker contains comment/tag, inFrame and outFrame.

for (AXrLottieMarker marker : lottieDrawable.getMarkers()) {
    Log.i("AXrLottie", marker.toString());
}

You can select a marker in AXrLottieDrawable and set start&end frame of the animation with an AXrLottieMarker :

lottieDrawable.selectMarker(MARKER);

Markers in a JSON:

"markers":[{"tm":IN_FRAME,"cm":"COMMENT","dr":DURATION},...]

Example :

"markers":[{"tm":0,"cm":"first","dr":69.33},{"tm":69.33,"cm":"second","dr":69.33},{"tm":138.66,"cm":"third","dr":67.33}]

Back to contents

Lottie2Gif

you can export lottie animations as a GIF! thanks to gif-h

AXrLottie2Gif.create(lottieDrawable)
                .setListener(new AXrLottie2Gif.Lottie2GifListener() {
                    long start;

                    @Override
                    public void onStarted() {
                        start = System.currentTimeMillis();
                    }

                    @Override
                    public void onProgress(int frame, int totalFrame) {
                        log("progress : " + frame + "/" + totalFrame);
                    }

                    @Override
                    public void onFinished() {
                        log("GIF created (" + (System.currentTimeMillis() - start) + "ms)\r\n" +
                                "Resolution : " + gifSize + "x" + gifSize + "\r\n" +
                                "Path : " + file.getAbsolutePath() + "\r\n" +
                                "File Size : " + (file.length() / 1024) + "kb");
                    }
                })
                .setBackgroundColor(Color.WHITE)
                .setOutputPath(file)
                .setSize(gifSize, gifSize)
                .setBackgroundTask(true)
                .setDithering(false)
                .setDestroyable(true)
                .build();

Output

lottie.gif has been exported by AXrLottie2Gif

Back to contents

Listeners

OnFrameChangedListener:

void onFrameChanged(AXrLottieDrawable drawable, int frame);
void onRepeat (int repeatedCount,boolean lastFrame);
void onStop();
void onStart();
void onRecycle();

OnFrameRenderListener:

void onUpdate(AXrLottieDrawable drawable, int frame, long timeDiff, boolean force);
Bitmap renderFrame(AXrLottieDrawable drawable, Bitmap bitmap, int frame);

Back to contents

NetworkFetcher

Simple way to load lottie from URL (SimpleNetworkFetcher) :

AXrLottieDrawable.fromURL(URL)
    .build()

AXrLottie has a default network fetching stack built on HttpURLConnection. However, if you would like to hook into your own network stack for performance, caching, or analytics, you may replace the internal stack with your own.

AXrLottie.setNetworkFetcher(OkHttpNetworkFetcher.create());

AXrLottieDrawable.fromURL(URL)
    .build()

Back to contents

FileExtension

FileExtension specifies which type of files can be used in lottie.

As default, AXrLottie supports JSON , ZIP (must have a json file) , GZIP (just like .tgs).

You can add more FileExtensions (such as .7z).

Example :

AXrLottie.addFileExtension(new SevenZipFileExtension());   
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;

public class SevenZipFileExtension extends AXrFileExtension {

    public SevenZipFileExtension() {
        super(".7z");
    }

    @Override
    public boolean canParseContent(String contentType) {
        // check content-type
        return contentType.contains("application/x-7z-compressed");
    }

    @Override
    public File toFile(String cache, File input, boolean fromNetwork) throws IOException {
        // read 7zip file and extract animation.
        SevenZFile sevenZFile = new SevenZFile(input);
        SevenZArchiveEntry entry = sevenZFile.getNextEntry();
        if (((List<SevenZArchiveEntry>) sevenZFile.getEntries()).size() > 1) {
            throw new IllegalArgumentException("7zip file must contains only one json file!");
        }
        File output = AXrLottie.getLottieCacheManager().getCachedFile(cache, JsonFileExtension.JSON, fromNetwork, false);
        if (entry != null) {
            FileOutputStream out = new FileOutputStream(output);
            byte[] content = new byte[(int) entry.getSize()];
            sevenZFile.read(content, 0, content.length);
            out.write(content);
            out.close();
        }
        sevenZFile.close();
        return output;
    }
}

Add Telegram Animated Stickers support :

AXrLottie.addFileExtension(new GZipFileExtension(".tgs"));

Back to contents

AXrLottieGlideDecoder

AXrLottieGlideDecoder is a Glide integration library for displaying AXrLottieDrawable.

Example :

Glide.with(this)
        .load(Uri.parse("file:///android_asset/loader.json"))
        .set(AXrLottieGlideOptions.ENABLED, true)
        .set(AXrLottieGlideOptions.NAME, "loader.json")
        .set(AXrLottieGlideOptions.NETWORK, false)
        .into(imageView);

Back to contents

AnimatedSticker - AXEmojiView

you can create AXrLottieImageView in AXEmojiView/StickerView using this code :

AXEmojiManager.setStickerViewCreatorListener(new StickerViewCreatorListener() {
    @Override
    public View onCreateStickerView(@NonNull Context context, @Nullable StickerCategory category, boolean isRecent) {
        return new AXrLottieImageView(context);
    }

    @Override
    public View onCreateCategoryView(@NonNull Context context) {
        return new AXrLottieImageView(context);
    }
});

add this just after AXEmojiManager.install

and you can load your animations in StickerProvider

  @Override
  public StickerLoader getLoader() {
        return new StickerLoader() {
            @Override
            public void onLoadSticker(View view, Sticker sticker) {
                if (view instanceof AXrLottieImageView && sticker instanceof AnimatedSticker) {
                    AXrLottieImageView lottieImageView = (AXrLottieImageView) view;
                    AnimatedSticker animatedSticker = (AnimatedSticker) sticker;
                    if (animatedSticker.drawable==null){
                        animatedSticker.drawable = Utils.createFromSticker(view.getContext(),animatedSticker,100);
                    }
                    lottieImageView.setLottieDrawable(animatedSticker.drawable);
                    lottieImageView.playAnimation();
                }
            }

            @Override
            public void onLoadStickerCategory(View view, StickerCategory stickerCategory, boolean selected) {
                if (view instanceof AXrLottieImageView) {
                    AXrLottieImageView lottieImageView = (AXrLottieImageView) view;
                    AnimatedSticker animatedSticker = (AnimatedSticker) stickerCategory.getCategoryData();
                    if (animatedSticker.drawable==null){
                        animatedSticker.drawable = Utils.createFromSticker(view.getContext(),animatedSticker,50);
                    }
                    lottieImageView.setLottieDrawable(animatedSticker.drawable);
                    //lottieImageView.playAnimation();
                }
            }
        };
  }

Output

Back to contents

AXrLottieEmoji

Preview

This sample appends lottie files as Emoji in TextView and EditText. Read More & Download Sample

Back to contents

Author

License

Copyright 2020 Amir Hossein Aghajari
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.



LCoders | AmirHosseinAghajari
Amir Hossein AghajariEmailGitHub