English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
This article introduces an example of the loading animation of iQIYI in Android, the specific code is as follows:
Illustration:
Knowledge points used:
If you are not familiar with Path and ValueAnimator, I recommend you to read these big guys' Blog, the most suitable articles for custom view, the detailed tutorial and practice of custom view, this is also a tutorial and practice, thank them for their efforts! (I hope everyone can carefully read it and get a lot of inspiration).
Animation disassembly
The difficulty here mainly lies in the calculation of coordinates, and I will explain it in detail next:
I believe that this diagram has been presented, combined with the sine and cosine functions, p1,p2,p3The coordinates are also determined.
p1.x = -(int) ((radius / 2 * Math.tan(30 * Math.PI / 180)));
p1.y = -radius / 2;
p2.x = p1.x;
p2.y = radius / 2;
p3.x = (int) (radius / 2 / Math.sin(60 * Math.PI / 180));
p3.y = 0;
Define some properties
private static final String DEFAULT_COLOR = "#00ba9b"; private static final int DEFAULT_SIZE = 50; //Default size private static final int DRAW_CIRCLE = 10001; //Statusmarke Zeichnen des Kreises und des Dreiecks, Ausführen der Animationen zum Zeichnen des Kreises private static final int ROTATE_TRIANGLE = 10002; //Statusmarke Ausführen der Animationen zur Rotation des Dreiecks und zur Einkerbung des Kreises private Context mContext; private Paint trianglePaint; //Malerei des Dreiecks private Paint circlePaint; //Kreismalerei private float paintStrokeWidth = 1; // Setze den Durchmesser des Kreises private long duration = 800; //Ausführungszeit private int mWidth; //Breite und Höhe des Views private int mHeight; private Path trianglePath; //Pfad des Dreiecks private Path circlePath; //Pfad des Kreises private Path dst; //Path, berechnet durch pathMeasure private Point p1, p2, p3; //Drei Punkte des Dreiecks private ValueAnimator animator; //Eigenschaftsanimation hauptsächlich um 0 zu erhalten-1Wert um die Animation auszuführen private float mAnimatorValue = 0; //Speicher die erhaltenen 0-1Wert private int mCurrentState = 0; //Aktuelle Zustand private int radius = 0; //Kreisradius private float startSegment; //Länge des Anfangssegments des Kreises private PathMeasure mMeasure; //Path-Messung private int triangleColor = -1; private int circleColor = -1;
Path-Einstellungen
1dawegen der Dreieck stets vorhanden ist, zeichne zunächst den Dreieck, verwende Path zum Zeichnen, wir kennen bereits die Koordinaten der drei Ecken des Dreiecks, das Zeichnen eines Dreiecks wird somit einfach.
trianglePath = new Path(); p1 = new Point(); p2 = new Point(); p3 = new Point(); trianglePath.moveTo(p1.x, p1.y); trianglePath.lineTo(p2.x, p2.y); trianglePath.lineTo(p3.x, p3.y); trianglePath.close();
Somit ist der Path des Dreiecks eingerichtet, um den Pfad auf das Canvas zu zeichnen, genauer gesagt, canvans.drawPath().
2.Dann wird der Kreis gezeichnet, wie gesagt, der Kreis hat einen Schnitt, wir fügen den Kreis auch in den Path ein, da wir später die Ummantelung des Kreises berechnen müssen, diese Operationen werden vom Path unterstützt,
RectF circleRect = new RectF(-radius, -radius, radius, radius); circlePath.addArc(circleRect, 268, 358); // Das ist der Schnitt vom Kreis268°beginnt mit dem Zeichnen, zeichnet258°Ein Abstand von zwei Grad wird gelassen
Eigenschaftsanimation einstellen
Da die Animation eine Gruppe von 0 benötigt-1Daten
hier nutzen wir die Werte der Eigenschaftsanimation, um die Animation durchzuführen.
private void initAnimation() { TimeInterpolator timeInterpolator = new AccelerateDecelerateInterpolator(); animator = ValueAnimator.ofFloat(0, 1).setDuration(duration); animator.setInterpolator(timeInterpolator); animator.setRepeatMode(ValueAnimator.RESTART); animator.setRepeatCount(ValueAnimator.INFINITE); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mAnimatorValue = (float) animation.getAnimatedValue(); //hier bekommen wir eine 0-1Wert invalidate(); // hier wird neu gezeichnet } }); animator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { //这里进行状态转换,执行不同的动画 switch (mCurrentState) { case DRAW_CIRCLE: mCurrentState = ROTATE_TRIANGLE; break; case ROTATE_TRIANGLE: mCurrentState = DRAW_CIRCLE; break; default: break; } } }); }
onDraw
分析onDraw方法
protected void onDraw(Canvas canvas) { super.onDraw(canvas); //将原点移动到中心位置 canvas.translate(mWidth / 2, mHeight / 2); // 重置path dst dst.reset(); //判断当前的状态 switch (mCurrentState) { //这里就是我们说的第一种状态 case DRAW_CIRCLE: //这一行是获取需要截取的path(dst)的开始位置,我们仔细观察动画可以看出,圆的开始是由一个位置向 //两端去画的,这个位置大约是圆的1/5,当画到了圆的起点的时候就从圆的起点开始绘制,我把执行这个动画 //的时间大致设置为0-1 的0.3的位置左右。 startSegment = (float) (mMeasure.getLength() / 5 * ((0.3 - mAnimatorValue) > 0 &63; (0.3 - mAnimatorValue) : 0); //这里没什么就是绘制三角形 trianglePaint.setStyle(Paint.Style.FILL_AND_STROKE); canvas.drawPath(trianglePath, trianglePaint); //这个方法就是获取你要截取的片段,第一个参数是开始的位置,第二个参数是结束的位置,第三个参数是 //数是截取后的path,添加到path(dst),注意是添加不是替换所以前面要reset,第四个参数是,是 //是否移动起点到当前路径的起点以保持dst中的路径不变(举个例子,如果dst中之前是有path的,这里 //设置false,此时就会保证dst的连续性而移动dst后加入的路径的起点到上一个路径的终点,从而保持连续性) mMeasure.getSegment(startSegment, mMeasure.getLength()) * mAnimatorValue, dst, true); canvas.drawPath(dst, circlePaint); break; //Zweite Animation case ROTATE_TRIANGLE: //Speichern Sie das Bild, da zwei Animationen ausgeführt werden müssen, speichern Sie das Bild im ursprünglichen Zustand canvas.save(); //Dann führen wir zunächst die Rotation des Dreiecks aus trianglePaint.setStyle(Paint.Style.FILL_AND_STROKE); canvas.rotate(360 * mAnimatorValue); canvas.drawPath(trianglePath, trianglePaint); //Restaurieren Sie das Bild canvas.restore(); //Dann verschwindet die äußere Kugel, der Verschwinden-Effekt ist im Prinzip gleich dem Zeichnen eines Kreises, hier haben wir eine Gruppe von 0-1der sich ändernden Werte, wir müssen nur //Wenn Sie die Szene schneiden, lassen Sie den Anfang immer näher an die Gesamtlänge heranrücken, dann erscheint ein Verschwinden-Effekt. mMeasure.getSegment(mMeasure.getLength(), * mAnimatorValue, mMeasure.getLength(), dst, true); canvas.drawPath(dst, circlePaint); break; default: break; } }
Das ist der Abschluss dieses Artikels. Wir hoffen, dass er Ihnen bei Ihrem Lernen hilft und dass Sie die呐喊教程大力支持.
Erklärung: Der Inhalt dieses Artikels wurde aus dem Internet entnommen und gehört dem Urheberrecht des jeweiligen Autors. Der Inhalt wurde von Internetnutzern freiwillig beigesteuert und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht manuell bearbeitet. Sie übernimmt auch keine rechtlichen Verantwortlichkeiten. Wenn Sie urheberrechtlich anstößige Inhalte entdecken, sind Sie herzlich eingeladen, eine E-Mail an notice#w zu senden.3codebox.com (Bitte ersetzen Sie # durch @, wenn Sie eine E-Mail senden, um zu melden, und fügen Sie relevante Beweise bei. Sobald nachgewiesen, wird diese Website die beanstandeten urheberrechtlichen Inhalte sofort löschen.)