English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Questo articolo introduce un esempio di animazione di caricamento di imitazione di iQIYI per Android, il codice specifico è il seguente:
Esempio di effetto:
Concetti utilizzati:
Se non sei familiare con Path e ValueAnimator, ti consiglio di leggere i Blog di questi grandi esperti, gli articoli su come creare view personalizzate che mi sembrano i migliori, la guida dettagliata e la pratica su come creare view personalizzate, questo è anche un tutorial e una pratica, grazie al loro impegno! (Spero che possiate leggere attentamente e ottenere molte ispirazioni).
Decomponi l'animazione
Il punto più difficile qui è il calcolo delle coordinate, e ne parlerò in dettaglio nel seguito:
Credo che con questo grafico, combinando le funzioni seno e coseno, le coordinate di p1, p2, p3 sono state determinate.
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;
Definisci alcune proprietà
private static final String DEFAULT_COLOR = "#00ba9b"; private static final int DEFAULT_SIZE = 50; // Dimensione predefinita private static final int DRAW_CIRCLE = 10001; // Marcatura di stato Disegna il cerchio e il triangolo Esegui l'animazione di disegno del cerchio private static final int ROTATE_TRIANGLE = 10002; // Marcatura di stato Esegui l'animazione di rotazione del triangolo e richiudi il cerchio private Context mContext; private Paint trianglePaint; // Pennello del triangolo private Paint circlePaint; // Pennello del cerchio private float paintStrokeWidth = 1; // Imposta la larghezza del cerchio private long duration = 800; //Tempo di esecuzione private int mWidth; //Larghezza e altezza della View private int mHeight; private Path trianglePath; //Percorso del triangolo private Path circlePath; //Percorso del cerchio private Path dst; //Percorso calcolato da pathMeasure private Point p1, p2, p3; //I tre punti del triangolo private ValueAnimator animator; //Animazione delle proprietà, principalmente per ottenere il valore 0-1 per eseguire l'animazione private float mAnimatorValue = 0; //Valore ottenuto per memorizzare il valore 0-1 private int mCurrentState = 0; //Stato corrente private int radius = 0; //Raggio del cerchio private float startSegment; //Lunghezza di inizio del cerchio private PathMeasure mMeasure; //Misura del percorso private int triangleColor = -1; private int circleColor = -1;
Impostazione del percorso
1. Poiché il triangolo esiste sempre, disegniamo prima il triangolo utilizzando il percorso. Sappiamo già le coordinate dei tre vertici del triangolo, quindi disegnare il triangolo diventa molto facile.
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();
In questo modo, il percorso del triangolo è stato configurato. Basta chiamare canvans.drawPath() per disegnare il triangolo sulla tela.
2. Poi è tempo di disegnare un cerchio, come è stato menzionato in precedenza, il cerchio ha una fessura. In questo caso, aggiungiamo anche il cerchio al percorso, poiché dobbiamo calcolare la circonferenza del cerchio in seguito. Queste operazioni vengono gestite dal percorso.
circlePath = new Path(); RectF circleRect = new RectF(-radius, -radius, radius, radius); circlePath.addArc(circleRect, 268, 358); // 这个是从圆的268°开始画,画258°空出两度的一个缺口
设置属性动画
由于动画需要一组0-1的数据
这里我们借用属性动画提供给我们的数值来实现动画。
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(); //这里我们将会拿到一个0-1的值 invalidate(); // 这里进行重绘 } }); 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) { //qui si esegue la transizione di stato, eseguendo diversi animazioni switch (mCurrentState) { case DRAW_CIRCLE: mCurrentState = ROTATE_TRIANGLE; break; case ROTATE_TRIANGLE: mCurrentState = DRAW_CIRCLE; break; default: break; } } }); }
onDraw
analizzare il metodo onDraw
protected void onDraw(Canvas canvas) { super.onDraw(canvas); //sposta l'origine al centro della posizione canvas.translate(mWidth / 2, mHeight / 2); //resetta il percorso dst dst.reset(); //giudicare lo stato corrente switch (mCurrentState) { //qui è lo stato di cui stiamo parlando case DRAW_CIRCLE: //questa riga è per ottenere la posizione di inizio del percorso da troncare (dst), osservando attentamente l'animazione si può vedere che il punto di partenza del cerchio è un //è disegnato ai due estremi, questa posizione è circa un quinto del cerchio, quando si arriva al punto di partenza del cerchio, si inizia a disegnare dal punto di partenza del cerchio, ho eseguito questa animazione //l'intervallo di tempo è impostato approssimativamente tra 0-1 alla posizione 0.3. circa. startSegment = (float) (mMeasure.getLength() / 5 * ((0.3 - mAnimatorValue) > 0 ? (0.3 - mAnimatorValue) : 0)); //qui non c'è nulla, è solo per disegnare un triangolo trianglePaint.setStyle(Paint.Style.FILL_AND_STROKE); canvas.drawPath(trianglePath, trianglePaint); //questo metodo è per ottenere il segmento che vuoi troncare, il primo parametro è la posizione di inizio, il secondo parametro è la posizione di fine, il terzo parametro è //il numero è il percorso troncato, aggiunto al percorso (dst), attenzione che non è una sostituzione ma un'aggiunta, quindi prima deve essere resettato, il quarto parametro è //deve spostare il punto di partenza al punto di partenza del percorso corrente mantenendo invariato il percorso in dst (per esempio, se dst contiene un percorso //impostò a false, in questo modo si garantisce la continuità di dst e si aggiunge il punto di partenza del percorso aggiunto dopo il movimento a fine percorso, mantenendo la continuità) mMeasure.getSegment(startSegment, mMeasure.getLength() * mAnimatorValue, dst, true); canvas.drawPath(dst, circlePaint); break; //Secondo tipo di animazione case ROTATE_TRIANGLE: //Salva il contesto del disegno, perché eseguiremo due animazioni, salvando lo stato iniziale del contesto del disegno canvas.save(); //Esegui prima la rotazione del triangolo trianglePaint.setStyle(Paint.Style.FILL_AND_STROKE); canvas.rotate(360 * mAnimatorValue); canvas.drawPath(trianglePath, trianglePaint); //Ripristina il contesto del disegno canvas.restore(); //Poi c'è la scomparsa del cerchio esterno, che ha la stessa logica del disegno del cerchio. Ecco un valore che cambia da 0 a 1, tutto ciò che dobbiamo fare è //Quando si tronca il segmento, facendo avvicinarsi il punto di partenza alla lunghezza totale, si otterrà l'effetto di scomparsa mMeasure.getSegment(mMeasure.getLength() * mAnimatorValue, mMeasure.getLength(), dst, true); canvas.drawPath(dst, circlePaint); break; default: break; } }
Questo è tutto il contenuto dell'articolo. Spero che sia utile per la tua apprendimento e che tu supporti fortemente il tutorial di urla.
Dichiarazione: il contenuto di questo articolo è stato raccolto da Internet, di proprietà del rispettivo autore. Il contenuto è stato contribuito e caricato dagli utenti di Internet autonomamente. Questo sito non detiene i diritti di proprietà, non ha effettuato una revisione manuale e non assume alcuna responsabilità legale correlata. Se trovi contenuti sospetti di violazione del copyright, invia un'e-mail a notice#oldtoolbag.com (sostituisci # con @) per segnalare il problema e fornire prove pertinenti. Una volta verificata, questo sito eliminerà immediatamente il contenuto sospetto di violazione del copyright.