Project Address: Https://github.com/JeasonWong/SlackLoadingView
The old rules, the first effect.
The picture is so big.
After the first glimpse of the animation of the idea:
+ Two parallel lines, to use the linear equation y=kx+b
+ Two parallel lines, multiplied by the slope of the previous two parallel lines to 1, i.e. K1*k2=-1
+ Line to do circular motion is the constant change of K value
+ then the simple line length change
I'm sure a lot of people would have a similar idea at first sight, but when I went to the bathroom I realized I wanted to be complicated.
After the toilet after the train of thought:
Do not think the line is oblique, is an ordinary line segment, a LineTo (StartX and stopx, only y different)
The vertical of the line easier, direct canvas flip (after the Turn back)
The circular motion of the whole animation is also canvas flip (not back after the turn)
The single change of lines is still animated with attributes (this is necessary ...). )
Let the whole canvas rotate before the animation starts
This is too easy.
I split the animation into four steps:
Canvas rotation and line changes animation (Canvas Rotate lines change)
Canvas rotation animation (Canvas Rotate)
Canvas Rotation Circle Changes animation (Canvas Rotate Circle Change)
Lines Change animation (line changes)
Describes the following member variables and some initialization before detailed description
Member variable
/static State private final int status_still = 0;
Loaded state private Final int status_loading = 1;
Line maximum length private final int max_line_length = dp2px (GetContext (), 120);
Line shortest length private final int min_line_length = dp2px (GetContext (), 40);
Maximum interval long private final int max_duration = 3000;
Minimum interval length private final int min_duration = 500;
Private Paint Mpaint;
Private int[] Mcolors = new Int[]{0xb07ecbda, 0xb0e6a92c, 0xb0d6014d, 0xb05aba94};
private int mwidth, mheight;
Animation interval long private int mduration = min_duration;
Total line length private int mentirelinelength = Min_line_length;
Circular radius private int mcircleradius;
All animations private list<animator> manimlist = new arraylist<> ();
CANVAS starting angle of rotation private final int canvas_rotate_angle = 60;
Animation current state private int mstatus = Status_still;
Canvas rotation angle private int mcanvasangle;
Line length private float mlinelength;
Semicircle y-axis position private float Mcircley;
The first several animated private int mstep;
Class
private void Initview () {
mpaint = new Paint ();
Mpaint.setantialias (true);
Mpaint.setcolor (Mcolors[0]);
private void InitData () {
mcanvasangle = Canvas_rotate_angle;
Mlinelength = mentirelinelength;
Mcircleradius = MENTIRELINELENGTH/5;
Mpaint.setstrokewidth (Mcircleradius * 2);
Mstep = 0;
}
Animation of canvas rotation and line changes (Canvas Rotate lines change)
/** * Animation1 * Animation 1 * Canvas Rotate line change * Canvas rotation and lines changes animation/private void Startcrlcanim () {Collect
ion<animator> animlist = new arraylist<> ();
Valueanimator Canvasrotateanim = valueanimator.ofint (canvas_rotate_angle + 0, Canvas_rotate_angle + ); Canvasrotateanim.addupdatelistener (New Valueanimator.animatorupdatelistener () {@Override public void onanimationupd
Ate (Valueanimator animation) {mcanvasangle = (int) animation.getanimatedvalue ();
}
});
Animlist.add (Canvasrotateanim);
Valueanimator Linewidthanim = Valueanimator.offloat (Mentirelinelength,-mentirelinelength); Linewidthanim.addupdatelistener (New Valueanimator.animatorupdatelistener () {@Override public void onanimationupdate (Valueanimator animation)
{mlinelength = (float) animation.getanimatedvalue ();
Invalidate ();
}
});
Animlist.add (Linewidthanim);
Animatorset animationset = new Animatorset ();
Animationset.setduration (mduration); AniMationset.playtogether (animlist);
Animationset.setinterpolator (New Linearinterpolator ()); Animationset.addlistener (New Animatorlistener () {@Override public void Onanimationend (animator animation) {Log
. D ("@=>", "Animation 1 End");
if (Mstatus = = status_loading) {mstep++;
Startcranim ();
}
}
});
Animationset.start ();
Manimlist.add (Animationset);
}
The first animation involves two animations at the same time, so using the Animatorset, this class is very powerful, you can make n animation at the same time (Playtogether), you can also make N animation sequential execution (playsequentially).
Here, in fact, my four animation is in order, but each animation has a simultaneous animation, in order to explain the convenience, I was listening to the onanimationend to control the animation sequence, in fact, can directly use playsequentially.
The top animation does two things:
2, line length change, from Mentirelinelength to-mentirelinelength.
The corresponding OnDraw method:
@Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas);
Switch (mstep% 4) {case 0:for (int i = 0; i < mcolors.length; i++) {Mpaint.setcolor (mcolors[i)); DRAWCRLC (Canvas, MWIDTH/2-mentirelinelength/2.2f, MHEIGHT/2-Mlinelength, MWIDTH/2-mentirelinelength/2.2f,
MHEIGHT/2 + mentirelinelength, mpaint, Mcanvasangle + i * 90);
} break;
...
} } ... private void DRAWCRLC (Canvas Canvas, float startx, float starty, float stopx, float stopy, @NonNull Paint Paint,
int rotate) {canvas.rotate (rotate, MWIDTH/2, MHEIGHT/2); Canvas.drawarc (New RECTF (Startx-mcircleradius, Starty-mcircleradius, StartX + Mcircleradius, StartY + MCircleRadius),
180, 180, true, mpaint);
Canvas.drawline (StartX, Starty, stopx, stopy, paint); Canvas.drawarc (New RECTF (Stopx-mcircleradius, Stopy-mcircleradius, Stopx + Mcircleradius, StopY + MCircleRadius), 0, 1
(a), true, Mpaint); Canvas.rotate (-rotate, MWIDTH/2, MHEIGHT/2);
}
is not very witty, DRAWCRLC did three things:
1. The canvas rotates and spins back.
2, Draw semicircle (why to draw semicircle?) Not drawing the whole circle? Leave a study questions here. )
3, Draw the line
So the animation 1 is complete.
Second, the canvas rotation animation (Canvas Rotate)
/** * Animation2 * Animation 2 * Canvas Rotate * Canvas rotation animation/private void Startcranim () {Valueanimator Canvasrotatea
Nim = Valueanimator.ofint (mcanvasangle, Mcanvasangle + 180);
Canvasrotateanim.setduration (MDURATION/2);
Canvasrotateanim.setinterpolator (New Linearinterpolator ()); Canvasrotateanim.addupdatelistener (New Valueanimator.animatorupdatelistener () {@Override public void onanimationupd
Ate (Valueanimator animation) {mcanvasangle = (int) animation.getanimatedvalue ();
Invalidate ();
}
});
Canvasrotateanim.addlistener (New Animatorlistener () {@Override public void Onanimationend (animator animation) {
LOG.D ("@=>", "Animation 2 End");
if (Mstatus = = status_loading) {mstep++;
Startcrccanim ();
}
}
});
Canvasrotateanim.start ();
Manimlist.add (Canvasrotateanim);
@Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas); Switch (mstep% 4) {... case 1:for (int i = 0; i < Mcolors.lenGth
i++) {Mpaint.setcolor (mcolors[i]);
DRAWCR (Canvas, MWIDTH/2-mentirelinelength/2.2f, MHEIGHT/2 + mentirelinelength, mpaint, Mcanvasangle + i * 90);
} break;
...
} } ... private void Drawcr (Canvas Canvas, float x, float y, @NonNull Paint Paint, int rotate) {canvas.rotate (rotate,
MWIDTH/2, MHEIGHT/2);
Canvas.drawcircle (x, y, Mcircleradius, paint);
Canvas.rotate (-rotate, MWIDTH/2, MHEIGHT/2);
}
With animation 1 of the foundation, then this is too easy, just a simple rotating canvas.
Three, the canvas rotation circle changes animation (Canvas Rotate Circle Change)
/** * Animation3 * Animation 3 * Canvas Rotate Circle change * Canvas rotation circle changes animation/private void Startcrccanim () {Collect
ion<animator> animlist = new arraylist<> ();
Valueanimator Canvasrotateanim = Valueanimator.ofint (Mcanvasangle, Mcanvasangle +, Mcanvasangle + 180); Canvasrotateanim.addupdatelistener (New Valueanimator.animatorupdatelistener () {@Override public void onanimationupd
Ate (Valueanimator animation) {mcanvasangle = (int) animation.getanimatedvalue ();
}
});
Animlist.add (Canvasrotateanim);
Valueanimator Circleyanim = Valueanimator.offloat (Mentirelinelength, MENTIRELINELENGTH/4, mEntireLineLength); Circleyanim.addupdatelistener (New Valueanimator.animatorupdatelistener () {@Override public void onanimationupdate (V
Alueanimator animation) {Mcircley = (float) animation.getanimatedvalue ();
Invalidate ();
}
});
Animlist.add (Circleyanim);
Animatorset animationset = new Animatorset (); Animationset.setduration (mDuRation);
Animationset.playtogether (animlist);
Animationset.setinterpolator (New Linearinterpolator ()); Animationset.addlistener (New Animatorlistener () {@Override public void Onanimationend (animator animation) {Log
. D ("@=>", "Animation 3 End");
if (Mstatus = = status_loading) {mstep++;
Startlcanim ();
}
}
});
Animationset.start ();
Manimlist.add (Animationset);
@Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas);
Switch (mstep% 4) {... case 2:for (int i = 0; i < mcolors.length; i++) {Mpaint.setcolor (mcolors[i));
DRAWCRCC (Canvas, MWIDTH/2-mentirelinelength/2.2f, MHEIGHT/2 + Mcircley, mpaint, Mcanvasangle + i * 90);
} break;
...
} } ... private void Drawcrcc (Canvas Canvas, float x, float y, @NonNull Paint Paint, int rotate) {canvas.rotate (rotat
E, MWIDTH/2, MHEIGHT/2);
Canvas.drawcircle (x, y, Mcircleradius, paint); Canvas.rotate (-rotate, MWIDTH/2, Mheight/ 2);
}
The animation 3 does two things:
1. Rotating Canvas
2, change the y-coordinate of circle, to achieve the effect of shrinking
Four, lines change animation (line changes)
/** * Animation4 * Animation 4 * Line changes * Lines change animation/private void Startlcanim () {Valueanimator Linewidthanim =
Valueanimator.offloat (Mentirelinelength,-mentirelinelength);
Linewidthanim.setduration (mduration);
Linewidthanim.setinterpolator (New Linearinterpolator ()); Linewidthanim.addupdatelistener (New Valueanimator.animatorupdatelistener () {@Override public void onanimationupdate (Valueanimator animation)
{mlinelength = (float) animation.getanimatedvalue ();
Invalidate ();
}
}); Linewidthanim.addlistener (New Animatorlistener () {@Override public void Onanimationend (animator animation) {Lo
G.D ("@=>", "Animation 4 End");
if (Mstatus = = status_loading) {mstep++;
Startcrlcanim ();
}
}
});
Linewidthanim.start ();
Manimlist.add (Linewidthanim);
@Override protected void OnDraw (Canvas Canvas) {Super.ondraw (Canvas); Switch (mstep% 4) {... case 3:for (int i = 0; i < mcolors.length; i++) {MPAint.setcolor (Mcolors[i]); DRAWLC (Canvas, MWIDTH/2-mentirelinelength/2.2f, MHEIGHT/2 + mentirelinelength, MWIDTH/2-MENTIRELINELENGTH/2.
2f, MHEIGHT/2 + mlinelength, mpaint, Mcanvasangle + i * 90);
} break; } ... private void Drawlc (Canvas Canvas, float startx, float starty, float stopx, float stopy, @NonNull Paint pain
T, int rotate) {canvas.rotate (rotate, MWIDTH/2, MHEIGHT/2); Canvas.drawarc (New RECTF (Startx-mcircleradius, Starty-mcircleradius, StartX + Mcircleradius, StartY + MCircleRadius),
0, 180, true, mpaint);
Canvas.drawline (StartX, Starty, stopx, stopy, paint); Canvas.drawarc (New RECTF (Stopx-mcircleradius, Stopy-mcircleradius, Stopx + Mcircleradius, StopY + MCircleRadius), 180,
180, true, mpaint);
Canvas.rotate (-rotate, MWIDTH/2, MHEIGHT/2);
}
Animation 4 only makes a change in line.
So the whole slack loading animation is done, is not very simple.
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.