自定义控件-绕着圆形轨迹旋转的小球
http://blog.csdn.net/xingxing_yan/article/details/54730068 轉(zhuǎn)載
http://www.cnblogs.com/jiayongji/p/5560806.html
一. 概述
用過華為手機(jī)的人應(yīng)該知道華為手機(jī)系統(tǒng)應(yīng)用中的加載動(dòng)畫是一個(gè)小球繞著圓圈旋轉(zhuǎn),之前有一個(gè)項(xiàng)目用過類似的功能,所以寫了一個(gè)自定義的控件,記錄一下。希望能給需要這個(gè)功能的同志們提供一些思路。先上效果圖:?
二. 思路
我們分析一下,一個(gè)小球繞著圓運(yùn)動(dòng),首先需要一個(gè)小球,那么自定義控件繪制一個(gè)小球。然后需要一個(gè)圓環(huán),最后設(shè)置小球在圓環(huán)上的一個(gè)起始位置,執(zhí)行旋轉(zhuǎn)動(dòng)畫即可。接下來就開始動(dòng)手吧。
三. 實(shí)現(xiàn)
1. 繪制小球
繪制小球很簡(jiǎn)單,自定義一個(gè)控件,重寫onDraw方法,繪制一個(gè)實(shí)心圓就好,這里就不多說了,直接上代碼:?
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. 實(shí)現(xiàn)圓形軌跡
(1) 寫一個(gè)控件AroundCircleBall繼承RelativeLayout,然后在此控件中繪制一個(gè)圓環(huán)
//圓形軌跡的中心的(圓的半徑+小球的半徑) 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); }因?yàn)樾∏虻闹行狞c(diǎn)在圓形軌跡上,所以整個(gè)AroundCircleBall的寬度和高度都是圓形軌跡的半徑+小球的半徑
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //測(cè)量控件寬高 int width = (int) (getPaddingLeft() + mCircleRadius * 2 + mBallRadius * 2 + getPaddingRight()); int height = (int) (getPaddingTop() + mCircleRadius * 2 + mBallRadius * 2 + getPaddingBottom()); setMeasuredDimension(width, height); }?
(2) 添加小球到AroundCircleBall中,計(jì)算初始位置,初始位置在圓的最底部。
private void init() {...mBall = new BallView(getContext());mBall.setRadius(mBallRadius);mBall.setBallColor(mBallColor);//小球的初始位置在圓環(huán)的最底部 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); ... }?
到此,我們圓環(huán)和小球的初始化都做完了,就下來就是讓小球繞著圓形軌跡旋轉(zhuǎn)。?
(3) 旋轉(zhuǎn)動(dòng)畫:?
小球需要繞著圓環(huán)旋轉(zhuǎn),我們首先需要計(jì)算旋轉(zhuǎn)的中心。View中提供兩個(gè)方法setPivotX()和 setPivotY() 方法來設(shè)置要旋轉(zhuǎn)View的中心點(diǎn)。這里注意一下,pivotX和pivotY的坐標(biāo)點(diǎn)是相對(duì)View自身坐標(biāo)系的,如果使用屏幕坐標(biāo)系可能會(huì)出現(xiàn)位置錯(cuò)亂。?
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
提供四種設(shè)置動(dòng)畫的補(bǔ)間器:先加速在減速,勻速,加速,減速
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
最后就是對(duì)動(dòng)畫的操作,提供啟動(dòng),暫停,取消三個(gè)方法:
/*** 啟動(dòng)旋轉(zhuǎn)動(dòng)畫*/public void startRotate(){if (mRotateAnim != null){ mRotateAnim.start(); } } /** * 暫停旋轉(zhuǎn)動(dòng)畫 */ @RequiresApi(api = Build.VERSION_CODES.KITKAT) public void pauseRotate(){ if (mRotateAnim != null && mRotateAnim.isRunning()){ mRotateAnim.pause(); } } /** * 取消旋轉(zhuǎn)動(dòng)畫 */ 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
到此,整個(gè)自定義控件AroundCircleBall就寫完了,接下來就用吧。?
(4) 使用?
布局文件:
?
在代碼中啟動(dòng)動(dòng)畫:
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mAcb = (AroundCircleBall) findViewById(R.id.main_acb);mAcb.startRotate();}?
真?zhèn)€過程并沒有很難的地方,唯一需要注意的就是旋轉(zhuǎn)中心點(diǎn)是要被旋轉(zhuǎn)的View自身坐標(biāo)系中的點(diǎn),不是屏幕坐標(biāo)系的。?
(5) 可以看到上邊的布局文件中有一些屬性是自定義的,方便我們?cè)诓季治募性O(shè)置一些參數(shù),自定義屬性如下:
http://blog.csdn.net/u010800708/article/details/49780085 另外一個(gè)例子
轉(zhuǎn)載于:https://www.cnblogs.com/wcLT/p/7689486.html
總結(jié)
以上是生活随笔為你收集整理的自定义控件-绕着圆形轨迹旋转的小球的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 九宫格抽奖
- 下一篇: MSD3458开发资料