自定义控件-绕着圆形轨迹旋转的小球
http://blog.csdn.net/xingxing_yan/article/details/54730068 轉載
http://www.cnblogs.com/jiayongji/p/5560806.html
一. 概述
用過華為手機的人應該知道華為手機系統應用中的加載動畫是一個小球繞著圓圈旋轉,之前有一個項目用過類似的功能,所以寫了一個自定義的控件,記錄一下。希望能給需要這個功能的同志們提供一些思路。先上效果圖:?
二. 思路
我們分析一下,一個小球繞著圓運動,首先需要一個小球,那么自定義控件繪制一個小球。然后需要一個圓環,最后設置小球在圓環上的一個起始位置,執行旋轉動畫即可。接下來就開始動手吧。
三. 實現
1. 繪制小球
繪制小球很簡單,自定義一個控件,重寫onDraw方法,繪制一個實心圓就好,這里就不多說了,直接上代碼:?
BallView:
1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
2. 實現圓形軌跡
(1) 寫一個控件AroundCircleBall繼承RelativeLayout,然后在此控件中繪制一個圓環
//圓形軌跡的中心的(圓的半徑+小球的半徑) mCircleCenterPoint = new PointF(mCircleRadius + mBallRadius, mCircleRadius + mBallRadius); ... @Overrideprotected void onDraw(Canvas canvas) { //繪制圓 mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(mStrokeWidth); mPaint.setColor(mCircleColor); canvas.drawCircle(mCircleCenterPoint.x, mCircleCenterPoint.y, mCircleRadius, mPaint); super.onDraw(canvas); }因為小球的中心點在圓形軌跡上,所以整個AroundCircleBall的寬度和高度都是圓形軌跡的半徑+小球的半徑
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //測量控件寬高 int width = (int) (getPaddingLeft() + mCircleRadius * 2 + mBallRadius * 2 + getPaddingRight()); int height = (int) (getPaddingTop() + mCircleRadius * 2 + mBallRadius * 2 + getPaddingBottom()); setMeasuredDimension(width, height); }?
(2) 添加小球到AroundCircleBall中,計算初始位置,初始位置在圓的最底部。
private void init() {...mBall = new BallView(getContext());mBall.setRadius(mBallRadius);mBall.setBallColor(mBallColor);//小球的初始位置在圓環的最底部 LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); params.leftMargin = (int) (mCircleRadius); params.topMargin = (int) (mCircleRadius * 2); mBall.setLayoutParams(params); addView(mBall); ... }?
到此,我們圓環和小球的初始化都做完了,就下來就是讓小球繞著圓形軌跡旋轉。?
(3) 旋轉動畫:?
小球需要繞著圓環旋轉,我們首先需要計算旋轉的中心。View中提供兩個方法setPivotX()和 setPivotY() 方法來設置要旋轉View的中心點。這里注意一下,pivotX和pivotY的坐標點是相對View自身坐標系的,如果使用屏幕坐標系可能會出現位置錯亂。?
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
提供四種設置動畫的補間器:先加速在減速,勻速,加速,減速
private Interpolator getInterpolator(){Interpolator interpolator = null;switch (mInterpolator){case ACCELERATE_DECELERATE_INTERPOLATOR: //先加上后減速 interpolator = new AccelerateDecelerateInterpolator(); break; case LINEAR_INTERPOLATOR: //勻速 interpolator = new LinearInterpolator(); break; case ACCELERATE: //加速 interpolator = new AccelerateInterpolator(); break; case DECELERATE: //減速 interpolator = new DecelerateInterpolator(); break; } return interpolator; }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
最后就是對動畫的操作,提供啟動,暫停,取消三個方法:
/*** 啟動旋轉動畫*/public void startRotate(){if (mRotateAnim != null){ mRotateAnim.start(); } } /** * 暫停旋轉動畫 */ @RequiresApi(api = Build.VERSION_CODES.KITKAT) public void pauseRotate(){ if (mRotateAnim != null && mRotateAnim.isRunning()){ mRotateAnim.pause(); } } /** * 取消旋轉動畫 */ public void cancelRotate(){ if (mRotateAnim != null){ mRotateAnim.cancel(); } }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
到此,整個自定義控件AroundCircleBall就寫完了,接下來就用吧。?
(4) 使用?
布局文件:
?
在代碼中啟動動畫:
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mAcb = (AroundCircleBall) findViewById(R.id.main_acb);mAcb.startRotate();}?
真個過程并沒有很難的地方,唯一需要注意的就是旋轉中心點是要被旋轉的View自身坐標系中的點,不是屏幕坐標系的。?
(5) 可以看到上邊的布局文件中有一些屬性是自定義的,方便我們在布局文件中設置一些參數,自定義屬性如下:
http://blog.csdn.net/u010800708/article/details/49780085 另外一個例子
轉載于:https://www.cnblogs.com/wcLT/p/7689486.html
總結
以上是生活随笔為你收集整理的自定义控件-绕着圆形轨迹旋转的小球的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 九宫格抽奖
- 下一篇: MSD3458开发资料