Android Custom View Series path drawing imitation Alipay payment successful animation _android

Source: Internet
Author: User

Objective

When paying with Alipay, we can see that success or failure will have an animated hint, if we need to do this, of course, you can let the designer to make you a GIF, but we know that the image memory consumption, we can use code implementation or code to achieve a better point.

Effect

Implementation methods

First we need to understand the Pathmeasure class, which we can understand to manage path. We mainly look at several methods.

pathmeasure (): constructs a method that instantiates an object

pathmeasure (Path Path,boolean isclosed): incoming Path object and closed, path object cannot be empty

GetLength (): Gets the current outline, the total length of the shape, if no Path object is set, returns 0

getsegment (float startd,float stopd,path dst,boolean startwithmoveto): Call this method, we can get to the specified range of contour, into the DST parameters. Therefore, the parameter passed in by this method is the start value of the length, the ending value, the path object that is loaded, and whether MoveTo. In addition, this method returns a Boolean type and, if GetLength is 0, returns false, or STARTD > STOPD, returning False.

SetPath (Path Path, Boolean isclosed): set path for current Pathmeasure object

nextcontour (): move to next profile

Then we need to move, we know the invalidate () method can refresh the interface, that is, call the OnDraw () method, so we have to call the Invalidate method, change the parameters in the OnDraw method, so as to achieve the effect of moving. So you can use the GetSegment method just introduced, constantly changing the range of acquisition from 0 * GetLength, to 1 * getlength, and finally draw complete. So we need a change of a value from 0 to 1 in a second or within two seconds, so we use the Valueanimator class to implement it.

Instantiate object
mcircleanimator = valueanimator.offloat (0, 1);
Set the length to 1000ms
mcircleanimator.setduration (1000);
Start animation
Mcircleanimator.start ();
Set up animation listening
Mcircleanimator.addupdatelistener (this);

When the animation starts, get the current progress in the listener method and redraw the image

Mcirclepercent = (float) animation.getanimatedvalue ();
Invalidate ();

In the OnDraw method, draw the image

Draw round
mpathcircle.addcircle (getwidth ()/2, getwidth ()/2, getwidth ()/2-mlinewidth, Path.Direction.CW);
Mpathmeasure.setpath (mpathcircle, false);
Mpathmeasure.getsegment (0, Mcirclepercent * mpathmeasure.getlength (), MPATHCIRCLEDST, true);
Canvas.drawpath (MPATHCIRCLEDST, mpaint);

Enclosed source code, welcome to comment

Package Com.mintmedical.wavedemo;
Import Android.animation.ValueAnimator;
Import Android.content.Context;
Import Android.graphics.Canvas;
Import Android.graphics.Color;
Import Android.graphics.Paint;
Import Android.graphics.Path;
Import Android.graphics.PathMeasure;
Import Android.util.AttributeSet;
Import Android.util.Log;

Import Android.view.View;
 /** * Created by Mooreli on 2016/12/12. 
 * * public class Resultanimation extends View implements Valueanimator.animatorupdatelistener {private context mcontext;
 /** * Paint object/private Paint mpaint;
 /** * path and corresponding empty path are used to populate the * * Private path mpathcircle;
 Private Path MPATHCIRCLEDST;
 Private Path mpathright;
 Private Path MPATHRIGHTDST;
 Private Path mPathWrong1;
 Private Path mPathWrong2;
 Private Path MPATHWRONG1DST;
 Private Path MPATHWRONG2DST;
 /** * Path Management * * Private pathmeasure mpathmeasure;
 /** * Animation/private valueanimator mcircleanimator;
 Private Valueanimator Mrightanimator; Private Valueanimator MWRong1animator;
 Private Valueanimator Mwrong2animator;
 /** * Current drawing progress as a percentage of the total path length * * Private float mcirclepercent;
 private float mrightpercent;
 private float mwrong1percent;
 private float mwrong2percent;
 /** * Line width */private int mlinewidth;
 /** * Correct animation error animation/public static final int result_right = 1;
 public static final int result_wrong = 2;

 /** * Current Result type */private int mresulttype = Result_wrong;
  Public Resultanimation {Super (context);
  Mcontext = context;
 Init ();
  Public resultanimation (context, AttributeSet attrs) {Super (context, attrs);
  Mcontext = context;
 Init (); 
  Public resultanimation (context, AttributeSet attrs, int defstyleattr) {Super (context, attrs, defstyleattr);
  Mcontext = context;
 Init ();
  private void Init () {mlinewidth = dp2px (3);
  Mpaint = new Paint ();
  Mpaint.setantialias (TRUE);
  Mpaint.setstrokewidth (Mlinewidth);
  Mpaint.setstyle (Paint.Style.STROKE); Mpaint.setcolor (ColOr.

  GREEN);
 Initpath ();
  private void Initpath () {mpathcircle = new Path ();
  MPATHCIRCLEDST = new Path ();
  Mpathright = new Path ();
  MPATHRIGHTDST = new Path ();
  MPathWrong1 = new Path ();
  MPathWrong2 = new Path ();
  MPATHWRONG1DST = new Path ();

  MPATHWRONG2DST = new Path ();

  Mpathmeasure = new Pathmeasure ();
  Instantiate object mcircleanimator = Valueanimator.offloat (0, 1);
  Set the length to 1000ms mcircleanimator.setduration (1000);
  Start animation Mcircleanimator.start ();

  Set up animation listening Mcircleanimator.addupdatelistener (this);
  Mrightanimator = valueanimator.offloat (0, 1);
  Mrightanimator.setduration (500);

  Mrightanimator.addupdatelistener (this);
  Mwrong1animator = valueanimator.offloat (0, 1);
  Mwrong1animator.setduration (300);
  Mwrong1animator.addupdatelistener (this);
  Mwrong2animator = valueanimator.offloat (0, 1);
  Mwrong2animator.setduration (300);

 Mwrong2animator.addupdatelistener (this);
  } @Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas); if (Mresulttype = = result_right) {mpaint.setcolor (color.green);
  else {mpaint.setcolor (color.red);
  ///Draw round Mpathcircle.addcircle (getwidth ()/2, getwidth ()/2, getwidth ()/2-mlinewidth, Path.Direction.CW);
  Mpathmeasure.setpath (mpathcircle, false);
  Mpathmeasure.getsegment (0, Mcirclepercent * mpathmeasure.getlength (), MPATHCIRCLEDST, true);
  Canvas.drawpath (MPATHCIRCLEDST, mpaint);
   if (Mresulttype = = result_right) {//Draw to tick Mpathright.moveto (getwidth ()/4, getwidth ()/2);
   Mpathright.lineto (GetWidth ()/2, GetWidth ()/4 * 3);
   Mpathright.lineto (GetWidth ()/4 * 3, GetWidth ()/4);
    if (mcirclepercent = = 1) {mpathmeasure.nextcontour ();
    Mpathmeasure.setpath (Mpathright, false);
    Mpathmeasure.getsegment (0, Mrightpercent * mpathmeasure.getlength (), MPATHRIGHTDST, true);
   Canvas.drawpath (MPATHRIGHTDST, mpaint);
   } else {Mpathwrong1.moveto (getwidth ()/4 * 3, GetWidth ()/4); Mpathwrong1.lineto (GetWidth ()/4, GetWidth ()/4 * 3);

   Mpathwrong2.moveto (GetWidth ()/4, GetWidth ()/4);

   Mpathwrong2.lineto (GetWidth ()/4 * 3, GetWidth ()/4 * 3);
    if (mcirclepercent = = 1) {mpathmeasure.nextcontour ();
    Mpathmeasure.setpath (mPathWrong1, false);
    Mpathmeasure.getsegment (0, Mwrong1percent * mpathmeasure.getlength (), MPATHWRONG1DST, true);
   Canvas.drawpath (MPATHWRONG1DST, mpaint);
    } if (mwrong1percent = = 1) {mpathmeasure.nextcontour ();
    Mpathmeasure.setpath (MPathWrong2, false);
    Mpathmeasure.getsegment (0, Mwrong2percent * mpathmeasure.getlength (), MPATHWRONG2DST, true);
   Canvas.drawpath (MPATHWRONG2DST, mpaint);
  }} private int dp2px (int dp) {Float scale = mcontext.getresources (). Getdisplaymetrics (). density;
 return (int) (Scale * DP + 0.5f); @Override public void Onanimationupdate (Valueanimator animation) {//Circular animation if (Animation.equals (Mcircleanimator))
   {mcirclepercent = (float) animation.getanimatedvalue ();
   Invalidate (); LOG.E ("TEST", "percent:" +Mcirclepercent);
    if (mcirclepercent = = 1) {if (Mresulttype = = result_right) Mrightanimator.start ();
   else Mwrong1animator.start (); 
   }///correct tick animation else if (Animation.equals (Mrightanimator)) {mrightpercent = (float) animation.getanimatedvalue ();
  Invalidate ();
   ///Error Right animation else if (Animation.equals (Mwrong1animator)) {mwrong1percent = (float) animation.getanimatedvalue ();
   Invalidate ();
   if (mwrong1percent = = 1) {Mwrong2animator.start (); The left animation else if (Animation.equals (Mwrong2animator)) {mwrong2percent = (float) animation.getanimatedvalue (
   );
  Invalidate ();
  } public void Setmresulttype (int mresulttype) {this.mresulttype = Mresulttype;
 Invalidate (); /** * Fixed write dead wide, can be redeployed manually * * @param widthmeasurespec * @param heightmeasurespec/@Override protected void O
  nmeasure (int widthmeasurespec, int heightmeasurespec) {super.onmeasure (Widthmeasurespec, Heightmeasurespec); SetmeasureddimensioN (dp2px), dp2px (50));

 }
}

GitHub Address: Https://github.com/lizebinbin

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.