Search code examples
android-studiolottie

Is it possible to recolor a lottie animation programmatically?


If I have a lottie animation in the form of a json file, is there a way to recolor it in code or even within the json itself?

(To be clear, I hope there's a way to do it without involving After Effects. For instance if I decide to change my app's primary color, the whole app will change except the animation unless there's a way to do that.)


Solution

  • I figured it out. For this example, let's say I want to recolor a specific layer to Color.RED.

    You'll need your LottieAnimationView, a KeyPath, and a LottieValueCallback

    private LottieAnimationView lottieAnimationVIew;
    private KeyPath mKeyPath;
    private LottieValueCallback<Integer> mCallback;
    

    Then in your onCreate (or onViewCreated for a fragment) you'll get the animation with findViewById, as well as "addLottieOnCompositionLoadedListener" to the lottieAnimationView, in which you will setup the "mKeyPath" and "mCallback":

    lottieAnimationVIew = findViewById(R.id.animationView);
    
    lottieAnimationView.addLottieOnCompositionLoadedListener(new LottieOnCompositionLoadedListener() {
      @Override
      public void onCompositionLoaded(LottieComposition composition) {
        mKeyPath = getKeyPath(); // This is your own method for getting the KeyPath you desire. More on that below.
        mCallback = new LottieValueCallback<>();
        mCallback.setValue(Color.RED);
        checkBox.addValueCallback(mKeyPath, LottieProperty.COLOR, mCallback);
      }
    });
    

    The argument "LottieProperty.COLOR" specifies which property I am changing.

    There's probably a better way to do this, but here's my "getKeyPath" method for finding the specific thing I want to change. It will log every KeyPath so you can see which one you want. Then it returns it once you've supplied the correct index. I saw that the one I want is the 5th in the list, hence the hard-coded index of 4.

    private KeyPath getKeyPath() {
      List<KeyPath> keyPaths = lottieAnimationView.resolveKeyPath(new KeyPath("Fill", "Ellipse 1", "Fill 1"));
            
      for (int i = 0; i < keyPaths.size(); i++) {
        Log.i("KeyPath", keyPaths.get(i).toString());
      }
            
      if (keyPaths.size() == 5) {
        return keyPaths.get(4);
      }
      else {
        return null;
      }
    }
    

    Note that the "Fill", "Ellipse 1", "Fill 1" are strings I supplied to narrow the list down to just the ones that have those keys, because I know that the layer I want will be among those. There's likely a better way to do this as well.