Animated Button on Android using AfterEffects and Lottie












1














I have a question about my implementation of a "special" Next-Button.

First I want to show you my AfterEffects file:

GIF Button Animation





So This Animation has 3 parts




  • Green: Entry correct

  • Red: Entry incorrect

  • Blue: Button has been pressed (visual feedback)




As I could not work this out with AVD and states I decided to use the Lottie library and play the different segments.

Main Activity - Only TestMethod, nothing really to review actually



private void initButtonTwo(){
mNext = findViewById(R.id.next);
mNextButton = new CancelCheckButton(mNext, new NextButtonListener() {
@Override
public void onClick() {

if(enableVibration){
vibrateFeedback();
}

switch (mNextCounter){
//This is just a Test-Method, i want Tick and Cross to alternate
case 1:
case 3:
mNextButton.showTick();
break;
case 2:
case 4:
mNextButton.showCross();
break;
case 5:
mNextButton.showTickEnd();
break;
}

if(mNextCounter >= 5){
mNextCounter = 1;
}else{
mNextCounter = mNextCounter + 1;
}
}
});
}




Interface for Communication Main -> Custom Button C



public interface NextButtonListener {
public void onClick();
}




Custom Class CancelCheckButton



public class CancelCheckButton implements View.OnTouchListener, Animator.AnimatorListener {

private LottieAnimationView mAnimationView;
private NextButtonListener mListener;
private final String LOG_TAG = this.getClass().getSimpleName();



public CancelCheckButton(LottieAnimationView mView, final NextButtonListener mListener){
this.mAnimationView = mView;
this.mListener = mListener;

this.setTouchListener();
this.setAnimatorListener();

Log.d(LOG_TAG, "CancelCheckButton: called");

}

private void setAnimatorListener(){
mAnimationView.addAnimatorListener(this);
Log.d(LOG_TAG, "CancelCheckButton: AnimatorListener called");
}

private void setTouchListener(){
mAnimationView.setOnTouchListener(this);
Log.d(LOG_TAG, "CancelCheckButton: TouchListener called");
}


/*****TOUCH INTERACTION ANIMATION*****/

public void showPressed(){
mAnimationView.setMinAndMaxFrame(452,462);
mAnimationView.setSpeed(1.8f);
mAnimationView.playAnimation();
Log.d(LOG_TAG, "CancelCheckButton: PressAnimation played");
}

public void showReleased(){
mAnimationView.setMinAndMaxFrame(485,495);
mAnimationView.setSpeed(1.8f);
mAnimationView.playAnimation();
Log.d(LOG_TAG, "CancelCheckButton: RelleaseAnimation played");
}


/*****FEDBACK CONTROL ANIMATION*****/

public void showTick(){
mAnimationView.setOnTouchListener(null);
mAnimationView.setMinAndMaxFrame(58,181);
mAnimationView.setSpeed(1.8f);
mAnimationView.playAnimation();
Log.d(LOG_TAG, "CancelCheckButton: TickAnimation played, Touchlistener deactivated");
}

public void showTickEnd(){
mAnimationView.setOnTouchListener(null);
mAnimationView.setMinAndMaxFrame(58,94);
mAnimationView.setSpeed(1.8f);
mAnimationView.playAnimation();
Log.d(LOG_TAG, "CancelCheckButton: TickEndAnimation played, Touchlistener deactivated");
}

public void showCross(){
mAnimationView.setOnTouchListener(null);
mAnimationView.setMinAndMaxFrame(300,431);
mAnimationView.setSpeed(2.0f);
mAnimationView.playAnimation();
Log.d(LOG_TAG, "CancelCheckButton: CrossAnimation played, Touchlistener deactivated");
}


/*****LISTENER*****/

@Override
public boolean onTouch(View v, MotionEvent event) {
if(v.getId() == mAnimationView.getId()){
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
showPressed();

Log.d(LOG_TAG, "CancelCheckButton: View is touched");
break;
case MotionEvent.ACTION_UP:
showReleased();

v.performClick();
mListener.onClick();


Log.d(LOG_TAG, "CancelCheckButton: View is relleased, OnClick is fired");
break;
}
}
return true;
}

@Override
public void onAnimationStart(Animator animation) {
Log.d(LOG_TAG, "CancelCheckButton: Called Animation is STARTED and Touchlistener deactivated");
}

@Override
public void onAnimationEnd(Animator animation) {
setTouchListener();
Log.d(LOG_TAG, "CancelCheckButton: Called Animation is FINISHED and Touchlistener reset");
}

@Override
public void onAnimationCancel(Animator animation) {
Log.d(LOG_TAG, "CancelCheckButton: Called Animation is CANCELED and Touchlistener reset");
}

@Override
public void onAnimationRepeat(Animator animation) {

}
}




Notes

When you click on the button I want the blue part to appear and disappear when the finger is released. As it is a very short animation I decided to not deactivate the OnTouchListener. No matter how fast I tipped I could not see a difference.


For the green or red part I deactivated the onTouchListener to avoid an accidental restart of the animation.


It actually works perfectly but even though I tried to keep the code clean I am not happy with it. Is there a more effective or at least a more common way to do it?










share|improve this question









New contributor




J. Lo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

























    1














    I have a question about my implementation of a "special" Next-Button.

    First I want to show you my AfterEffects file:

    GIF Button Animation





    So This Animation has 3 parts




    • Green: Entry correct

    • Red: Entry incorrect

    • Blue: Button has been pressed (visual feedback)




    As I could not work this out with AVD and states I decided to use the Lottie library and play the different segments.

    Main Activity - Only TestMethod, nothing really to review actually



    private void initButtonTwo(){
    mNext = findViewById(R.id.next);
    mNextButton = new CancelCheckButton(mNext, new NextButtonListener() {
    @Override
    public void onClick() {

    if(enableVibration){
    vibrateFeedback();
    }

    switch (mNextCounter){
    //This is just a Test-Method, i want Tick and Cross to alternate
    case 1:
    case 3:
    mNextButton.showTick();
    break;
    case 2:
    case 4:
    mNextButton.showCross();
    break;
    case 5:
    mNextButton.showTickEnd();
    break;
    }

    if(mNextCounter >= 5){
    mNextCounter = 1;
    }else{
    mNextCounter = mNextCounter + 1;
    }
    }
    });
    }




    Interface for Communication Main -> Custom Button C



    public interface NextButtonListener {
    public void onClick();
    }




    Custom Class CancelCheckButton



    public class CancelCheckButton implements View.OnTouchListener, Animator.AnimatorListener {

    private LottieAnimationView mAnimationView;
    private NextButtonListener mListener;
    private final String LOG_TAG = this.getClass().getSimpleName();



    public CancelCheckButton(LottieAnimationView mView, final NextButtonListener mListener){
    this.mAnimationView = mView;
    this.mListener = mListener;

    this.setTouchListener();
    this.setAnimatorListener();

    Log.d(LOG_TAG, "CancelCheckButton: called");

    }

    private void setAnimatorListener(){
    mAnimationView.addAnimatorListener(this);
    Log.d(LOG_TAG, "CancelCheckButton: AnimatorListener called");
    }

    private void setTouchListener(){
    mAnimationView.setOnTouchListener(this);
    Log.d(LOG_TAG, "CancelCheckButton: TouchListener called");
    }


    /*****TOUCH INTERACTION ANIMATION*****/

    public void showPressed(){
    mAnimationView.setMinAndMaxFrame(452,462);
    mAnimationView.setSpeed(1.8f);
    mAnimationView.playAnimation();
    Log.d(LOG_TAG, "CancelCheckButton: PressAnimation played");
    }

    public void showReleased(){
    mAnimationView.setMinAndMaxFrame(485,495);
    mAnimationView.setSpeed(1.8f);
    mAnimationView.playAnimation();
    Log.d(LOG_TAG, "CancelCheckButton: RelleaseAnimation played");
    }


    /*****FEDBACK CONTROL ANIMATION*****/

    public void showTick(){
    mAnimationView.setOnTouchListener(null);
    mAnimationView.setMinAndMaxFrame(58,181);
    mAnimationView.setSpeed(1.8f);
    mAnimationView.playAnimation();
    Log.d(LOG_TAG, "CancelCheckButton: TickAnimation played, Touchlistener deactivated");
    }

    public void showTickEnd(){
    mAnimationView.setOnTouchListener(null);
    mAnimationView.setMinAndMaxFrame(58,94);
    mAnimationView.setSpeed(1.8f);
    mAnimationView.playAnimation();
    Log.d(LOG_TAG, "CancelCheckButton: TickEndAnimation played, Touchlistener deactivated");
    }

    public void showCross(){
    mAnimationView.setOnTouchListener(null);
    mAnimationView.setMinAndMaxFrame(300,431);
    mAnimationView.setSpeed(2.0f);
    mAnimationView.playAnimation();
    Log.d(LOG_TAG, "CancelCheckButton: CrossAnimation played, Touchlistener deactivated");
    }


    /*****LISTENER*****/

    @Override
    public boolean onTouch(View v, MotionEvent event) {
    if(v.getId() == mAnimationView.getId()){
    switch(event.getAction()){
    case MotionEvent.ACTION_DOWN:
    showPressed();

    Log.d(LOG_TAG, "CancelCheckButton: View is touched");
    break;
    case MotionEvent.ACTION_UP:
    showReleased();

    v.performClick();
    mListener.onClick();


    Log.d(LOG_TAG, "CancelCheckButton: View is relleased, OnClick is fired");
    break;
    }
    }
    return true;
    }

    @Override
    public void onAnimationStart(Animator animation) {
    Log.d(LOG_TAG, "CancelCheckButton: Called Animation is STARTED and Touchlistener deactivated");
    }

    @Override
    public void onAnimationEnd(Animator animation) {
    setTouchListener();
    Log.d(LOG_TAG, "CancelCheckButton: Called Animation is FINISHED and Touchlistener reset");
    }

    @Override
    public void onAnimationCancel(Animator animation) {
    Log.d(LOG_TAG, "CancelCheckButton: Called Animation is CANCELED and Touchlistener reset");
    }

    @Override
    public void onAnimationRepeat(Animator animation) {

    }
    }




    Notes

    When you click on the button I want the blue part to appear and disappear when the finger is released. As it is a very short animation I decided to not deactivate the OnTouchListener. No matter how fast I tipped I could not see a difference.


    For the green or red part I deactivated the onTouchListener to avoid an accidental restart of the animation.


    It actually works perfectly but even though I tried to keep the code clean I am not happy with it. Is there a more effective or at least a more common way to do it?










    share|improve this question









    New contributor




    J. Lo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.























      1












      1








      1







      I have a question about my implementation of a "special" Next-Button.

      First I want to show you my AfterEffects file:

      GIF Button Animation





      So This Animation has 3 parts




      • Green: Entry correct

      • Red: Entry incorrect

      • Blue: Button has been pressed (visual feedback)




      As I could not work this out with AVD and states I decided to use the Lottie library and play the different segments.

      Main Activity - Only TestMethod, nothing really to review actually



      private void initButtonTwo(){
      mNext = findViewById(R.id.next);
      mNextButton = new CancelCheckButton(mNext, new NextButtonListener() {
      @Override
      public void onClick() {

      if(enableVibration){
      vibrateFeedback();
      }

      switch (mNextCounter){
      //This is just a Test-Method, i want Tick and Cross to alternate
      case 1:
      case 3:
      mNextButton.showTick();
      break;
      case 2:
      case 4:
      mNextButton.showCross();
      break;
      case 5:
      mNextButton.showTickEnd();
      break;
      }

      if(mNextCounter >= 5){
      mNextCounter = 1;
      }else{
      mNextCounter = mNextCounter + 1;
      }
      }
      });
      }




      Interface for Communication Main -> Custom Button C



      public interface NextButtonListener {
      public void onClick();
      }




      Custom Class CancelCheckButton



      public class CancelCheckButton implements View.OnTouchListener, Animator.AnimatorListener {

      private LottieAnimationView mAnimationView;
      private NextButtonListener mListener;
      private final String LOG_TAG = this.getClass().getSimpleName();



      public CancelCheckButton(LottieAnimationView mView, final NextButtonListener mListener){
      this.mAnimationView = mView;
      this.mListener = mListener;

      this.setTouchListener();
      this.setAnimatorListener();

      Log.d(LOG_TAG, "CancelCheckButton: called");

      }

      private void setAnimatorListener(){
      mAnimationView.addAnimatorListener(this);
      Log.d(LOG_TAG, "CancelCheckButton: AnimatorListener called");
      }

      private void setTouchListener(){
      mAnimationView.setOnTouchListener(this);
      Log.d(LOG_TAG, "CancelCheckButton: TouchListener called");
      }


      /*****TOUCH INTERACTION ANIMATION*****/

      public void showPressed(){
      mAnimationView.setMinAndMaxFrame(452,462);
      mAnimationView.setSpeed(1.8f);
      mAnimationView.playAnimation();
      Log.d(LOG_TAG, "CancelCheckButton: PressAnimation played");
      }

      public void showReleased(){
      mAnimationView.setMinAndMaxFrame(485,495);
      mAnimationView.setSpeed(1.8f);
      mAnimationView.playAnimation();
      Log.d(LOG_TAG, "CancelCheckButton: RelleaseAnimation played");
      }


      /*****FEDBACK CONTROL ANIMATION*****/

      public void showTick(){
      mAnimationView.setOnTouchListener(null);
      mAnimationView.setMinAndMaxFrame(58,181);
      mAnimationView.setSpeed(1.8f);
      mAnimationView.playAnimation();
      Log.d(LOG_TAG, "CancelCheckButton: TickAnimation played, Touchlistener deactivated");
      }

      public void showTickEnd(){
      mAnimationView.setOnTouchListener(null);
      mAnimationView.setMinAndMaxFrame(58,94);
      mAnimationView.setSpeed(1.8f);
      mAnimationView.playAnimation();
      Log.d(LOG_TAG, "CancelCheckButton: TickEndAnimation played, Touchlistener deactivated");
      }

      public void showCross(){
      mAnimationView.setOnTouchListener(null);
      mAnimationView.setMinAndMaxFrame(300,431);
      mAnimationView.setSpeed(2.0f);
      mAnimationView.playAnimation();
      Log.d(LOG_TAG, "CancelCheckButton: CrossAnimation played, Touchlistener deactivated");
      }


      /*****LISTENER*****/

      @Override
      public boolean onTouch(View v, MotionEvent event) {
      if(v.getId() == mAnimationView.getId()){
      switch(event.getAction()){
      case MotionEvent.ACTION_DOWN:
      showPressed();

      Log.d(LOG_TAG, "CancelCheckButton: View is touched");
      break;
      case MotionEvent.ACTION_UP:
      showReleased();

      v.performClick();
      mListener.onClick();


      Log.d(LOG_TAG, "CancelCheckButton: View is relleased, OnClick is fired");
      break;
      }
      }
      return true;
      }

      @Override
      public void onAnimationStart(Animator animation) {
      Log.d(LOG_TAG, "CancelCheckButton: Called Animation is STARTED and Touchlistener deactivated");
      }

      @Override
      public void onAnimationEnd(Animator animation) {
      setTouchListener();
      Log.d(LOG_TAG, "CancelCheckButton: Called Animation is FINISHED and Touchlistener reset");
      }

      @Override
      public void onAnimationCancel(Animator animation) {
      Log.d(LOG_TAG, "CancelCheckButton: Called Animation is CANCELED and Touchlistener reset");
      }

      @Override
      public void onAnimationRepeat(Animator animation) {

      }
      }




      Notes

      When you click on the button I want the blue part to appear and disappear when the finger is released. As it is a very short animation I decided to not deactivate the OnTouchListener. No matter how fast I tipped I could not see a difference.


      For the green or red part I deactivated the onTouchListener to avoid an accidental restart of the animation.


      It actually works perfectly but even though I tried to keep the code clean I am not happy with it. Is there a more effective or at least a more common way to do it?










      share|improve this question









      New contributor




      J. Lo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      I have a question about my implementation of a "special" Next-Button.

      First I want to show you my AfterEffects file:

      GIF Button Animation





      So This Animation has 3 parts




      • Green: Entry correct

      • Red: Entry incorrect

      • Blue: Button has been pressed (visual feedback)




      As I could not work this out with AVD and states I decided to use the Lottie library and play the different segments.

      Main Activity - Only TestMethod, nothing really to review actually



      private void initButtonTwo(){
      mNext = findViewById(R.id.next);
      mNextButton = new CancelCheckButton(mNext, new NextButtonListener() {
      @Override
      public void onClick() {

      if(enableVibration){
      vibrateFeedback();
      }

      switch (mNextCounter){
      //This is just a Test-Method, i want Tick and Cross to alternate
      case 1:
      case 3:
      mNextButton.showTick();
      break;
      case 2:
      case 4:
      mNextButton.showCross();
      break;
      case 5:
      mNextButton.showTickEnd();
      break;
      }

      if(mNextCounter >= 5){
      mNextCounter = 1;
      }else{
      mNextCounter = mNextCounter + 1;
      }
      }
      });
      }




      Interface for Communication Main -> Custom Button C



      public interface NextButtonListener {
      public void onClick();
      }




      Custom Class CancelCheckButton



      public class CancelCheckButton implements View.OnTouchListener, Animator.AnimatorListener {

      private LottieAnimationView mAnimationView;
      private NextButtonListener mListener;
      private final String LOG_TAG = this.getClass().getSimpleName();



      public CancelCheckButton(LottieAnimationView mView, final NextButtonListener mListener){
      this.mAnimationView = mView;
      this.mListener = mListener;

      this.setTouchListener();
      this.setAnimatorListener();

      Log.d(LOG_TAG, "CancelCheckButton: called");

      }

      private void setAnimatorListener(){
      mAnimationView.addAnimatorListener(this);
      Log.d(LOG_TAG, "CancelCheckButton: AnimatorListener called");
      }

      private void setTouchListener(){
      mAnimationView.setOnTouchListener(this);
      Log.d(LOG_TAG, "CancelCheckButton: TouchListener called");
      }


      /*****TOUCH INTERACTION ANIMATION*****/

      public void showPressed(){
      mAnimationView.setMinAndMaxFrame(452,462);
      mAnimationView.setSpeed(1.8f);
      mAnimationView.playAnimation();
      Log.d(LOG_TAG, "CancelCheckButton: PressAnimation played");
      }

      public void showReleased(){
      mAnimationView.setMinAndMaxFrame(485,495);
      mAnimationView.setSpeed(1.8f);
      mAnimationView.playAnimation();
      Log.d(LOG_TAG, "CancelCheckButton: RelleaseAnimation played");
      }


      /*****FEDBACK CONTROL ANIMATION*****/

      public void showTick(){
      mAnimationView.setOnTouchListener(null);
      mAnimationView.setMinAndMaxFrame(58,181);
      mAnimationView.setSpeed(1.8f);
      mAnimationView.playAnimation();
      Log.d(LOG_TAG, "CancelCheckButton: TickAnimation played, Touchlistener deactivated");
      }

      public void showTickEnd(){
      mAnimationView.setOnTouchListener(null);
      mAnimationView.setMinAndMaxFrame(58,94);
      mAnimationView.setSpeed(1.8f);
      mAnimationView.playAnimation();
      Log.d(LOG_TAG, "CancelCheckButton: TickEndAnimation played, Touchlistener deactivated");
      }

      public void showCross(){
      mAnimationView.setOnTouchListener(null);
      mAnimationView.setMinAndMaxFrame(300,431);
      mAnimationView.setSpeed(2.0f);
      mAnimationView.playAnimation();
      Log.d(LOG_TAG, "CancelCheckButton: CrossAnimation played, Touchlistener deactivated");
      }


      /*****LISTENER*****/

      @Override
      public boolean onTouch(View v, MotionEvent event) {
      if(v.getId() == mAnimationView.getId()){
      switch(event.getAction()){
      case MotionEvent.ACTION_DOWN:
      showPressed();

      Log.d(LOG_TAG, "CancelCheckButton: View is touched");
      break;
      case MotionEvent.ACTION_UP:
      showReleased();

      v.performClick();
      mListener.onClick();


      Log.d(LOG_TAG, "CancelCheckButton: View is relleased, OnClick is fired");
      break;
      }
      }
      return true;
      }

      @Override
      public void onAnimationStart(Animator animation) {
      Log.d(LOG_TAG, "CancelCheckButton: Called Animation is STARTED and Touchlistener deactivated");
      }

      @Override
      public void onAnimationEnd(Animator animation) {
      setTouchListener();
      Log.d(LOG_TAG, "CancelCheckButton: Called Animation is FINISHED and Touchlistener reset");
      }

      @Override
      public void onAnimationCancel(Animator animation) {
      Log.d(LOG_TAG, "CancelCheckButton: Called Animation is CANCELED and Touchlistener reset");
      }

      @Override
      public void onAnimationRepeat(Animator animation) {

      }
      }




      Notes

      When you click on the button I want the blue part to appear and disappear when the finger is released. As it is a very short animation I decided to not deactivate the OnTouchListener. No matter how fast I tipped I could not see a difference.


      For the green or red part I deactivated the onTouchListener to avoid an accidental restart of the animation.


      It actually works perfectly but even though I tried to keep the code clean I am not happy with it. Is there a more effective or at least a more common way to do it?







      java android animation






      share|improve this question









      New contributor




      J. Lo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question









      New contributor




      J. Lo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question








      edited yesterday









      mdfst13

      17.4k52156




      17.4k52156






      New contributor




      J. Lo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked yesterday









      J. Lo

      62




      62




      New contributor




      J. Lo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      J. Lo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      J. Lo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          0






          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });






          J. Lo is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f210949%2fanimated-button-on-android-using-aftereffects-and-lottie%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          J. Lo is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          J. Lo is a new contributor. Be nice, and check out our Code of Conduct.













          J. Lo is a new contributor. Be nice, and check out our Code of Conduct.












          J. Lo is a new contributor. Be nice, and check out our Code of Conduct.
















          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f210949%2fanimated-button-on-android-using-aftereffects-and-lottie%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          How to reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

          is 'sed' thread safe

          How to make a Squid Proxy server?