日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

自定义控件-绕着圆形轨迹旋转的小球

發布時間:2025/6/17 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自定义控件-绕着圆形轨迹旋转的小球 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://blog.csdn.net/xingxing_yan/article/details/54730068 轉載

http://www.cnblogs.com/jiayongji/p/5560806.html

一. 概述

用過華為手機的人應該知道華為手機系統應用中的加載動畫是一個小球繞著圓圈旋轉,之前有一個項目用過類似的功能,所以寫了一個自定義的控件,記錄一下。希望能給需要這個功能的同志們提供一些思路。先上效果圖:?

二. 思路

我們分析一下,一個小球繞著圓運動,首先需要一個小球,那么自定義控件繪制一個小球。然后需要一個圓環,最后設置小球在圓環上的一個起始位置,執行旋轉動畫即可。接下來就開始動手吧。

三. 實現

1. 繪制小球

繪制小球很簡單,自定義一個控件,重寫onDraw方法,繪制一個實心圓就好,這里就不多說了,直接上代碼:?
BallView:

public class BallView extends View { private int mBallColor = Color.BLACK; private float mRadius = 10f; private PointF mCenterPoint; private Paint mPaint; public BallView(Context context) { this(context, null); } public BallView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init(){ mPaint = new Paint(); mPaint.setAntiAlias(true); mCenterPoint = new PointF(mRadius, mRadius); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = (int) (getPaddingLeft() + 2*mRadius + getPaddingRight()); int height = (int) (getPaddingTop() + 2*mRadius + getPaddingBottom()); setMeasuredDimension(width, height); } @Override protected void onDraw(Canvas canvas) { mPaint.setStyle(Paint.Style.FILL); mPaint.setColor(mBallColor); canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, mRadius, mPaint); } public void setBallColor(int mBallColor) { this.mBallColor = mBallColor; } public void setRadius(float radius) { this.mRadius = radius; mCenterPoint.set(radius, radius); } public float getRadius() { return mRadius; } }

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自身坐標系的,如果使用屏幕坐標系可能會出現位置錯亂。?

private void initRotateAnim(){mRotateAnim = ObjectAnimator.ofFloat(mBall, "rotation", 0f, 360f); //計算小球旋轉的中心點(此點的左邊是在小球自身的坐標系中) float pivotX = mBall.getRadius(); float pivotY = mBall.getRadius() - mCircleRadius; mBall.setPivotX(pivotX); mBall.setPivotY(pivotY); mRotateAnim.setDuration(mDuration); mRotateAnim.setInterpolator(getInterpolator()); mRotateAnim.setRepeatCount(-1); mRotateAnim.setStartDelay(500); }
  • 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) 使用?
布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/activity_main"android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.yyx.simple.MainActivity"> <com.yyx.mylibrary.widget.AroundCircleBall android:id="@+id/main_acb" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:layout_centerInParent="true" app:ball_color="@android:color/holo_green_light" app:ball_radius="5dp" app:circle_color="@android:color/holo_blue_light" app:circle_width="1dp" app:circle_radius="40dp" app:rotate_duration="5" app:rotate_interpolator="accelerate_decelerate"/> </RelativeLayout>

?

在代碼中啟動動畫:

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mAcb = (AroundCircleBall) findViewById(R.id.main_acb);mAcb.startRotate();}

?

真個過程并沒有很難的地方,唯一需要注意的就是旋轉中心點是要被旋轉的View自身坐標系中的點,不是屏幕坐標系的。?
(5) 可以看到上邊的布局文件中有一些屬性是自定義的,方便我們在布局文件中設置一些參數,自定義屬性如下:

<!--AroundCircleBall自定義屬性--><declare-styleable name="AroundCircleBall"> <!--繪制圓形軌跡的線寬--> <attr name="circle_width" format="dimension"></attr> <!--繪制圓形軌跡的顏色--> <attr name="circle_color" format="color"></attr> <!--圓形軌跡的半徑--> <attr name="circle_radius" format="dimension"></attr> <!--小球的顏色--> <attr name="ball_color" format="color"></attr> <!--小球的半徑--> <attr name="ball_radius" format="dimension"></attr> <!--設置旋轉一周需要的時間(單位為秒)--> <attr name="rotate_duration" format="integer"></attr> <!--設置旋轉動畫的補間器--> <attr name="rotate_interpolator" format="enum"> <enum name="accelerate_decelerate" value="1"/> <enum name="linear" value="2"/> <enum name="accelerate" value="3"/> <enum name="decelerate" value="4"/> </attr> </declare-styleable>


http://blog.csdn.net/u010800708/article/details/49780085 另外一個例子

轉載于:https://www.cnblogs.com/wcLT/p/7689486.html

總結

以上是生活随笔為你收集整理的自定义控件-绕着圆形轨迹旋转的小球的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。