国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android仿視頻加載旋轉小球動畫效果的實例代碼

2019-10-21 21:39:17
字體:
來源:轉載
供稿:網友

先上個效果圖,以免大家跑錯地了。    

Android,視頻加載,旋轉,動畫,代碼

嗯,除了只能錄三秒,其他沒啥問題。   

下面分析一下怎么實現上面這個效果。    

理性分析后我們可以看到是幾個小球繞著一個圓進行運動,那這里面的重點我們看看什么。    

繪制五個球,沒什么難度,讓球繞圓進行運動,這個好像我們沒有見到是怎么去實現了,那下就說這個。    

從本質上看,球繞圓運動,其實我們可以看作是一個物體繞指定的路勁運動,那我們就有下面幾個東西需要說一下:

1:Path
2:ValueAnimator
3:PathMeasure  

前兩個大家應該都見過,一個是路徑,就是可以自己繪制路線的一個工具,一個是動畫,用來指定物體運動的工具,那第三個是一個關于測量路徑的類。    

下面說說PathMeasure的用法。    

首先是初始化:

pathMeasure = new PathMeasure(path, false);  

兩個參數第一個,第一個就是我們需要用到的路徑,第二個參數意思就是這個以路徑頭尾是否相連來計算結果,通常我們就寫false就行,不會有問題。    

然后是用法:

private float[] mCurrentPositionOne = new float[2];float value = (Float) animation.getAnimatedValue();pathMeasure.getPosTan(value, mCurrentPositionOne, null);  我們可以看見把一個二維數組放到了getPosTan這個方法里面,然后還有一個animation,這里的animation來自哪里呢?來自這里:valueAnimatorOne.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  @Override  public void onAnimationUpdate(ValueAnimator animation) {    // 獲取當前點坐標封裝到mCurrentPosition    float value = (Float) animation.getAnimatedValue();    pathMeasure.getPosTan(value, mCurrentPositionOne, null);    postInvalidate();  }});

看見沒,是動畫的監聽里面來的,getPosTan的最后一個參數通常也就寫null就行了,那么這整個一行的代碼意思就是當動畫發生了變化,就執行這行代碼,然后這行代碼會把這個時間點的路徑上的坐標賦值給mCurrentPositionOne。   

那我們獲取到看這個路徑上的坐標點怎么辦呢?   

立馬用來ondraw里面啊,我的小球此時就可以根據這個坐標點去繪制自己的位置,這個的話,當動畫開始時,小球就會不斷接受新的坐標,然后不斷重繪,最終產生旋轉小球的效果。     

我先把屬性動畫的代碼貼出來:

if (valueAnimatorOne == null) {   valueAnimatorOne = ValueAnimator.ofFloat(0, pathMeasure.getLength());  valueAnimatorOne.setDuration(800);  // 減速插值器  valueAnimatorOne.setInterpolator(new DecelerateInterpolator());  valueAnimatorOne.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {    @Override    public void onAnimationUpdate(ValueAnimator animation) {      // 獲取當前點坐標封裝到mCurrentPosition      float value = (Float) animation.getAnimatedValue();      pathMeasure.getPosTan(value, mCurrentPositionOne, null);      postInvalidate();    }  });  valueAnimatorOne.addListener(new Animator.AnimatorListener() {    @Override    public void onAnimationStart(Animator animator) {      finishAnimateOne = 1;    }    @Override    public void onAnimationEnd(Animator animator) {      finishAnimateOne = 0;    }    @Override    public void onAnimationCancel(Animator animator) {    }    @Override    public void onAnimationRepeat(Animator animator) {    }  });}valueAnimatorOne.start();

  我寫了個800,也就是動畫的維持時間,但是我們發現有啊后幾個小球,所以我們需要繪制好幾個小球,然后給他們不同的動畫,為什么呢?因為動畫都一樣,小球就疊加在一起了,我們就只能看見一個球了。   

說到這里的話,我們的目標算時完成了,具體的操作,大家參考以下代碼,或者去:android自定義View索引     

里面動畫的demo進行下載,大家隨意,下面給出代碼:

/** * 仿視頻加載動畫,旋轉的藍色小球 */public class RotaryBall extends View {  private Path rotationPath;  private float radius;  private Paint circlePaintOne;  private PathMeasure pathMeasure;  private int finishAnimateOne = 0;  // 用來判斷當前動畫有沒有開始  private int finishAnimateTwo = 0;  // 用來判斷當前動畫有沒有開始  private int finishAnimateThree = 0;  // 用來判斷當前動畫有沒有開始  private int finishAnimateFour = 0;  // 用來判斷當前動畫有沒有開始  private int finishAnimateFive = 0;  // 用來判斷當前動畫有沒有開始  private Handler handler;  private float[] mCurrentPositionOne = new float[2];  private float[] mCurrentPositionTwo = new float[2];  private float[] mCurrentPositionThree = new float[2];  private float[] mCurrentPositionFour = new float[2];  private float[] mCurrentPositionFive = new float[2];  private ValueAnimator valueAnimatorOne = null;  private ValueAnimator valueAnimatorTwo = null;  private ValueAnimator valueAnimatorThree = null;  private ValueAnimator valueAnimatorFour = null;  private ValueAnimator valueAnimatorFive = null;  private int currentStatus = -1;  //-1表示第一次運行,0表示動畫結束或者沒開始,1表示正在運動中  private boolean animateOrNot = true;  //用來決定是否開啟動畫  public RotaryBall(Context context) {    super(context);    initData();  }  public RotaryBall(Context context, AttributeSet attrs) {    super(context, attrs);    initData();  }  private void initData() {    rotationPath = new Path();    circlePaintOne = new Paint();    circlePaintOne.setColor(Color.BLUE);    circlePaintOne.setAntiAlias(true);    handler = new Handler() {      @Override      public void handleMessage(Message msg) {        super.handleMessage(msg);        switch (msg.what) {          case 4:            if (finishAnimateOne == 0) {              startAnimatorOne();            }            if (finishAnimateTwo == 0) {              startAnimatorTwo();            }            if (finishAnimateThree == 0) {              startAnimatorThree();            }            if (finishAnimateFour == 0) {              startAnimatorFour();            }            if (finishAnimateFive == 0) {              startAnimatorFive();            }            currentStatus = 0;        }      }    };  }  @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    super.onMeasure(widthMeasureSpec, heightMeasureSpec);    radius = getMeasuredWidth() / 2;  }  @Override  protected void onDraw(Canvas canvas) {    super.onDraw(canvas);//    rotationPath.addCircle(radius, radius, radius - 10, CW);    rotationPath.moveTo(radius, 0 + 10);    rotationPath.cubicTo(radius, 0 + 10, radius * 2 - 10, 0 + 10, radius * 2 - 10, radius);    rotationPath.cubicTo(radius * 2 - 10, radius, radius * 2 - 10, radius * 2 - 10, radius, radius * 2 - 10);    rotationPath.cubicTo(radius, radius * 2 - 10, 0 + 10, radius * 2 - 10, 0 + 10, radius);    rotationPath.cubicTo(0 + 10, radius, 0 + 10, 0 + 10, radius, 0 + 10);    rotationPath.close();    pathMeasure = new PathMeasure(rotationPath, false);    //下面繪制不同半徑的小圓    canvas.drawCircle(mCurrentPositionOne[0], mCurrentPositionOne[1], 10, circlePaintOne);    canvas.drawCircle(mCurrentPositionTwo[0], mCurrentPositionTwo[1], 9, circlePaintOne);    canvas.drawCircle(mCurrentPositionThree[0], mCurrentPositionThree[1], 7, circlePaintOne);    canvas.drawCircle(mCurrentPositionFour[0], mCurrentPositionFour[1], 5, circlePaintOne);    canvas.drawCircle(mCurrentPositionFive[0], mCurrentPositionFive[1], 3, circlePaintOne);    if (currentStatus == -1) {      Message message = new Message();      message.what = 4;      handler.sendMessage(message);    }    if (animateOrNot) {      if (currentStatus == 0) {        currentStatus = 1;        new Thread() {      //用線程來統一五個圓的周期          @Override          public void run() {            super.run();            try {              Log.d("thread", "thread");              Thread.sleep(1600);              Message message = new Message();              message.what = 4;              handler.sendMessage(message);            } catch (InterruptedException e) {              e.printStackTrace();            }          }        }.start();      }    }  }  //供外部調用,開始動畫  public void startAnimate() {    if (!animateOrNot) {      animateOrNot = true;      currentStatus = -1;      invalidate();    }  }  //供外部調用,停止動畫  public void stopAnimate() {    if (animateOrNot) {      animateOrNot = false;    }  }  //界面被銷毀  @Override  protected void onDetachedFromWindow() {    super.onDetachedFromWindow();    stopAnimate();    clearAllAnimation();  }  //清除所有動畫效果  private void clearAllAnimation() {    if (valueAnimatorOne != null){      if (valueAnimatorOne.isRunning()){        valueAnimatorOne.cancel();      }      valueAnimatorOne.removeAllUpdateListeners();      valueAnimatorOne = null;    }    if (valueAnimatorTwo != null){      if (valueAnimatorTwo.isRunning()){        valueAnimatorTwo.cancel();      }      valueAnimatorTwo.removeAllUpdateListeners();      valueAnimatorTwo = null;    }    if (valueAnimatorThree != null){      if (valueAnimatorThree.isRunning()){        valueAnimatorThree.cancel();      }      valueAnimatorThree.removeAllUpdateListeners();      valueAnimatorThree = null;    }    if (valueAnimatorFour != null){      if (valueAnimatorFour.isRunning()){        valueAnimatorFour.cancel();      }      valueAnimatorFour.removeAllUpdateListeners();      valueAnimatorFour = null;    }    if (valueAnimatorFive != null){      if (valueAnimatorFive.isRunning()){        valueAnimatorFive.cancel();      }      valueAnimatorFive.removeAllUpdateListeners();      valueAnimatorFive = null;    }  }  //開始第一個小球的動畫  private void startAnimatorOne() {    if (valueAnimatorOne == null) {      Log.d("valueAnimatorOne", "valueAnimatorOne");      valueAnimatorOne = ValueAnimator.ofFloat(0, pathMeasure.getLength());      valueAnimatorOne.setDuration(800);      // 減速插值器      valueAnimatorOne.setInterpolator(new DecelerateInterpolator());      valueAnimatorOne.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {        @Override        public void onAnimationUpdate(ValueAnimator animation) {          // 獲取當前點坐標封裝到mCurrentPosition          float value = (Float) animation.getAnimatedValue();          pathMeasure.getPosTan(value, mCurrentPositionOne, null);          postInvalidate();        }      });      valueAnimatorOne.addListener(new Animator.AnimatorListener() {        @Override        public void onAnimationStart(Animator animator) {          finishAnimateOne = 1;        }        @Override        public void onAnimationEnd(Animator animator) {          finishAnimateOne = 0;        }        @Override        public void onAnimationCancel(Animator animator) {        }        @Override        public void onAnimationRepeat(Animator animator) {        }      });    }    valueAnimatorOne.start();  }  //開始第二個小球的動畫  private void startAnimatorTwo() {    if (valueAnimatorTwo == null) {      valueAnimatorTwo = ValueAnimator.ofFloat(0, pathMeasure.getLength());      valueAnimatorTwo.setDuration(1000);      // 減速插值器      valueAnimatorTwo.setInterpolator(new DecelerateInterpolator());      valueAnimatorTwo.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {        @Override        public void onAnimationUpdate(ValueAnimator animation) {          float value = (Float) animation.getAnimatedValue();          // 獲取當前點坐標封裝到mCurrentPosition          pathMeasure.getPosTan(value, mCurrentPositionTwo, null);          postInvalidate();        }      });      valueAnimatorTwo.addListener(new Animator.AnimatorListener() {        @Override        public void onAnimationStart(Animator animator) {          finishAnimateTwo = 1;        }        @Override        public void onAnimationEnd(Animator animator) {          finishAnimateTwo = 0;        }        @Override        public void onAnimationCancel(Animator animator) {        }        @Override        public void onAnimationRepeat(Animator animator) {        }      });    }    valueAnimatorTwo.start();  }  //開始第三個小球的動畫  private void startAnimatorThree() {    if (valueAnimatorThree == null) {      valueAnimatorThree = ValueAnimator.ofFloat(0, pathMeasure.getLength());      valueAnimatorThree.setDuration(1200);      // 減速插值器      valueAnimatorThree.setInterpolator(new DecelerateInterpolator());      valueAnimatorThree.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {        @Override        public void onAnimationUpdate(ValueAnimator animation) {          float value = (Float) animation.getAnimatedValue();          // 獲取當前點坐標封裝到mCurrentPosition          pathMeasure.getPosTan(value, mCurrentPositionThree, null);          postInvalidate();        }      });      valueAnimatorThree.addListener(new Animator.AnimatorListener() {        @Override        public void onAnimationStart(Animator animator) {          finishAnimateThree = 1;        }        @Override        public void onAnimationEnd(Animator animator) {          finishAnimateThree = 0;        }        @Override        public void onAnimationCancel(Animator animator) {        }        @Override        public void onAnimationRepeat(Animator animator) {        }      });    }    valueAnimatorThree.start();  }  //開始第四個小球的動畫  private void startAnimatorFour() {    if (valueAnimatorFour == null) {      valueAnimatorFour = ValueAnimator.ofFloat(0, pathMeasure.getLength());      valueAnimatorFour.setDuration(1400);      // 減速插值器      valueAnimatorFour.setInterpolator(new DecelerateInterpolator());      valueAnimatorFour.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {        @Override        public void onAnimationUpdate(ValueAnimator animation) {          float value = (Float) animation.getAnimatedValue();          // 獲取當前點坐標封裝到mCurrentPosition          pathMeasure.getPosTan(value, mCurrentPositionFour, null);          postInvalidate();        }      });      valueAnimatorFour.addListener(new Animator.AnimatorListener() {        @Override        public void onAnimationStart(Animator animator) {          finishAnimateFour = 1;        }        @Override        public void onAnimationEnd(Animator animator) {          finishAnimateFour = 0;        }        @Override        public void onAnimationCancel(Animator animator) {        }        @Override        public void onAnimationRepeat(Animator animator) {        }      });    }    valueAnimatorFour.start();  }  //開始第五個小球的動畫  private void startAnimatorFive() {    if (valueAnimatorFive == null) {      valueAnimatorFive = ValueAnimator.ofFloat(0, pathMeasure.getLength());      valueAnimatorFive.setDuration(1600);      // 減速插值器      valueAnimatorFive.setInterpolator(new DecelerateInterpolator());      valueAnimatorFive.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {        @Override        public void onAnimationUpdate(ValueAnimator animation) {          float value = (Float) animation.getAnimatedValue();          // 獲取當前點坐標封裝到mCurrentPosition          pathMeasure.getPosTan(value, mCurrentPositionFive, null);          postInvalidate();        }      });      valueAnimatorFive.addListener(new Animator.AnimatorListener() {        @Override        public void onAnimationStart(Animator animator) {          finishAnimateFive = 1;        }        @Override        public void onAnimationEnd(Animator animator) {          finishAnimateFive = 0;        }        @Override        public void onAnimationCancel(Animator animator) {        }        @Override        public void onAnimationRepeat(Animator animator) {        }      });    }    valueAnimatorFive.start();  }}

總結

以上所述是小編給大家介紹的Android仿視頻加載旋轉小球動畫實例代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VEVB武林網網站的支持!


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 麟游县| 兴宁市| 六枝特区| 江安县| 樟树市| 黑龙江省| 远安县| 治县。| 霞浦县| 大英县| 长武县| 改则县| 永仁县| 道孚县| 张家界市| 张家港市| 高碑店市| 阿巴嘎旗| 阳曲县| 聊城市| 晋中市| 蒲城县| 乌兰县| 胶州市| 西和县| 福州市| 夏河县| 津南区| 新源县| 子洲县| 惠来县| 阿拉善左旗| 云安县| 黑河市| 晋州市| 万安县| 巴青县| 彭水| 肥西县| 乐平市| 沂源县|