English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

android仿爱奇艺加载动画实例

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:

  1. Path
  2. ValueAnimator

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

  1. Un cerchio viene disegnato lentamente in senso orario (il cerchio non è un cerchio chiuso)
  2. Questo passo è un'animazione combinata, il cerchio scompare lentamente, contemporaneamente il triangolo ruota in senso orario

Il punto più difficile qui è il calcolo delle coordinate, e ne parlerò in dettaglio nel seguito:

  1. Qui mettiamo il centro come origine delle ascisse e delle ordinate, la direzione verso il basso è il verso positivo dell'asse x, e la direzione verso destra è il verso positivo dell'asse y. Se si imposta la dimensione del view come quadrata, in questo caso si può impostare il raggio del cerchio come metà della larghezza o dell'altezza. Se non è quadrato, si deve prendere la metà del valore minore tra la larghezza e l'altezza come raggio del cerchio.
  2. Poi c'è il triangolo, che è anche il punto più difficile per determinare le coordinate, questo triangolo è un triangolo equilatero, e ci aspettiamo che il triangolo giri intorno al centro del cerchio. Quindi la distanza dal centro del cerchio ai vari vertici del triangolo è uguale. Ho impostato che la lunghezza del lato del triangolo è il raggio del cerchio.

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.