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.