欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

android仿愛(ài)奇藝加載動(dòng)畫(huà)實(shí)例

 更新時(shí)間:2016年10月28日 16:03:54   作者:NiuGuLu  
這篇文章主要介紹了android仿愛(ài)奇藝加載動(dòng)畫(huà)實(shí)例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。

本篇文章介紹了android仿愛(ài)奇藝加載動(dòng)畫(huà)實(shí)例,具體代碼如下:

效果圖:

用到的知識(shí)點(diǎn):

  1. Path
  2. ValueAnimator

如果對(duì)Path和ValueAnimator還不熟悉推薦去看這幾個(gè)大神的Blog自定義view的目前講的最適合我的文章 ,自定義view的詳細(xì)教程和實(shí)踐,這個(gè)也是教程和實(shí)踐,感謝他們的付出!(希望大家可以認(rèn)真看完,可以得到很多啟發(fā))。

拆解動(dòng)畫(huà)

  1. 一個(gè)圓先順時(shí)針的慢慢畫(huà)出來(lái)(圓不是一個(gè)閉合的圓)
  2. 這一步是一個(gè)組合動(dòng)畫(huà),圓慢慢的消失,同時(shí)三角形順時(shí)針旋轉(zhuǎn)

這里的難點(diǎn)主要就是對(duì)坐標(biāo)的計(jì)算,接下來(lái)我會(huì)詳細(xì)的說(shuō)一下:

  1. 我們這里把圓心作為 x,y軸的起點(diǎn),向下方向?yàn)閤軸正向,向右方向是y軸的正向。如果設(shè)置view的大小是等寬高的,這個(gè)時(shí)候就可以把圓的半徑設(shè)置成寬或者高的一半,如果不是等寬高的就要取寬或者高的最小值的一半,作為圓的半徑。
  2. 接下來(lái)就是三角形,也是確定坐標(biāo)的難點(diǎn),這個(gè)三角形是一個(gè)等邊三角形,我們希望,三角形旋轉(zhuǎn)的時(shí)候也是繞圓心進(jìn)行旋轉(zhuǎn)。所以圓心到三角形的各個(gè)頂點(diǎn)的距離都是相等的,我這里設(shè)置的是,三角形的邊長(zhǎng)是圓的半徑。

相信這張圖拿出來(lái)了,結(jié)合正弦、余弦函數(shù),p1,p2,p3的坐標(biāo)也就出來(lái)了。

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;

定義一些屬性

private static final String DEFAULT_COLOR = "#00ba9b";
private static final int DEFAULT_SIZE = 50;  //默認(rèn)大小
private static final int DRAW_CIRCLE = 10001; //狀態(tài)標(biāo)記 畫(huà)出圓形和三角形 執(zhí)行畫(huà)出圓形的動(dòng)畫(huà)
private static final int ROTATE_TRIANGLE = 10002; //狀態(tài)標(biāo)記 執(zhí)行旋轉(zhuǎn)三角形和收回圓形的動(dòng)畫(huà)
private Context mContext;
private Paint trianglePaint;  //三角形的畫(huà)筆
private Paint circlePaint;  //圓形畫(huà)筆
private float paintStrokeWidth = 1; // 設(shè)置圓形的寬度
private long duration = 800; //執(zhí)行時(shí)間
private int mWidth; //View的寬高
private int mHeight;
private Path trianglePath; //三角形的路徑
private Path circlePath;  //圓形的路徑
private Path dst; //由pathMeasure計(jì)算后的path
private Point p1, p2, p3; //三角形的三個(gè)點(diǎn)
private ValueAnimator animator; //屬性動(dòng)畫(huà) 主要是獲取0-1的值來(lái)執(zhí)行動(dòng)畫(huà)
private float mAnimatorValue = 0;  //存放獲取到的0-1的值
private int mCurrentState = 0;  //當(dāng)前的狀態(tài) 
private int radius = 0; //圓的半徑
private float startSegment; //圓開(kāi)始畫(huà)的長(zhǎng)度
private PathMeasure mMeasure; //測(cè)量path
private int triangleColor = -1;
private int circleColor = -1;

設(shè)置path

1.因?yàn)槿切问且恢贝嬖诘?,就先?huà)三角,用path來(lái)畫(huà),我們已經(jīng)知道三角形的三個(gè)頂點(diǎn)的坐標(biāo)了,畫(huà)三角形就變得很容易了。

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();

這樣三角形的path就被設(shè)置好了,只要調(diào)用 canvans.drawPath() 就可以把三角形畫(huà)到畫(huà)布上。

2.然后就是畫(huà)圓,前面說(shuō)過(guò)圓是有一個(gè)缺口的,我們這里也把圓添加到path里面,之所以沒(méi)有直接畫(huà)到canvas上面,是因?yàn)楹竺嫖覀冞€要對(duì)圓的周長(zhǎng)進(jìn)行計(jì)算,這些操作path會(huì)幫我們操作,

circlePath = new Path();
RectF circleRect = new RectF(-radius, -radius, radius, radius);
circlePath.addArc(circleRect, 268, 358); // 這個(gè)是從圓的268°開(kāi)始畫(huà),畫(huà)258°空出兩度的一個(gè)缺口

設(shè)置屬性動(dòng)畫(huà)

由于動(dòng)畫(huà)需要一組0-1的數(shù)據(jù)
這里我們借用屬性動(dòng)畫(huà)提供給我們的數(shù)值來(lái)實(shí)現(xiàn)動(dòng)畫(huà)。

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(); //這里我們將會(huì)拿到一個(gè)0-1的值
        invalidate(); // 這里進(jìn)行重繪
      }
    });
    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) { 
       //這里進(jìn)行狀態(tài)轉(zhuǎn)換,執(zhí)行不同的動(dòng)畫(huà)
        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);
    //將原點(diǎn)移動(dòng)到中心位置
    canvas.translate(mWidth / 2, mHeight / 2);
    // 重置path dst
    dst.reset();
    //判斷當(dāng)前的狀態(tài)
    switch (mCurrentState) {
     //這里就是我們說(shuō)的第一種狀態(tài)
      case DRAW_CIRCLE:
      //這一行是獲取需要截取的path(dst)的開(kāi)始位置,我們仔細(xì)觀察動(dòng)畫(huà)可以看出,圓的開(kāi)始是由一個(gè)位置向
      //兩端去畫(huà)的,這個(gè)位置大約是圓的1/5,當(dāng)畫(huà)到了圓的起點(diǎn)的時(shí)候就從圓的起點(diǎn)開(kāi)始繪制,我把執(zhí)行這個(gè)動(dòng)畫(huà)
      //的時(shí)間大致的設(shè)置為0-1 的0.3的位置左右。
        startSegment = (float) (mMeasure.getLength() / 5 * ((0.3 - mAnimatorValue) > 0 ? (0.3 - mAnimatorValue) : 0));
        //這里沒(méi)什么就是繪制三角形
        trianglePaint.setStyle(Paint.Style.FILL_AND_STROKE);
        canvas.drawPath(trianglePath, trianglePaint);
        //這個(gè)方法就是獲取你要截取的片段,第一個(gè)參數(shù)是開(kāi)始的位置,第二個(gè)參數(shù)是結(jié)束的位置,第三個(gè)參
        //數(shù)是截取后的path,添加到path(dst),注意是添加不是替換所以前面要reset,第四個(gè)參數(shù)是,是
        //否要移動(dòng)起點(diǎn)到當(dāng)前路徑的起點(diǎn)保持dst中的路徑不變(舉個(gè)例子,如果dst中之前是有path的,這里
        //設(shè)置了false,此時(shí)就會(huì)保證dst的連續(xù)性而移動(dòng)dst后加入的路徑的起點(diǎn)到上一個(gè)路徑的終點(diǎn),從而保持連續(xù)性)
        mMeasure.getSegment(startSegment, mMeasure.getLength() * mAnimatorValue, dst, true);
        canvas.drawPath(dst, circlePaint);
        break;
         //第二種動(dòng)畫(huà)
      case ROTATE_TRIANGLE:
      //對(duì)畫(huà)布進(jìn)行保存,因?yàn)橐獔?zhí)行兩個(gè)動(dòng)畫(huà),保存初始狀態(tài)下的畫(huà)布
        canvas.save();
        //然后先執(zhí)行三角形的旋轉(zhuǎn)
        trianglePaint.setStyle(Paint.Style.FILL_AND_STROKE);
        canvas.rotate(360 * mAnimatorValue);
        canvas.drawPath(trianglePath, trianglePaint);
        //恢復(fù)畫(huà)布
        canvas.restore();
        //然后是外面圓的消失,消失其實(shí)和畫(huà)圓的道理是一樣的,這里我們有一組0-1的變化的值,我們只需要
        //截取片段的時(shí)候讓起點(diǎn)不斷的向總長(zhǎng)度靠近,就會(huì)出現(xiàn)消失的效果
        mMeasure.getSegment(mMeasure.getLength() * mAnimatorValue, mMeasure.getLength(), dst, true);
        canvas.drawPath(dst, circlePaint);
        break;
      default:
        break;
    }

  }

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論