最近,為了搞一個(gè)滑動(dòng)弧形的指示器,從中明白了一些關(guān)于圓盤,之類的自定義控件核心的一般做法。在此只是粗略表述一下,關(guān)于時(shí)間的表述,并不準(zhǔn)確。
效果如下圖所示。
package com.example.xxx.myapplication;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
/*** 表盤刻度值*/
public class WatchView extends View {private String TAG = WatchView.class.getSimpleName();
private Paint mPaintCircle;
private float mCircleRadius;
private float mCircleCenterX;
private float mCircleCenterY;
private float padding =
50;
private Paint mPaintDegree;
private int mDegreeCount =
24;
private Paint mTimeHourPointPaint;
private float mTimeHourLength =
0;
private float mTimeMinuteLength;
private float mTimeDegreeHourLength =
60;
private float mTimeDegreeMintueLength =
40;
private Paint mTimeMintuePointPaint;
private Mythread myThread;
private boolean startOpenThreadFlag =
false;
private int angle =
0;
public WatchView(Context context) {
this(context,
null);init(
null,
0);}
public WatchView(Context context, AttributeSet attrs) {
this(context, attrs,
0);init(attrs,
0);}
public WatchView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);init(attrs, defStyleAttr);}
private void init(AttributeSet attrs,
int defStyle) {mPaintCircle =
new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintCircle.setStrokeWidth(
10);mPaintCircle.setStyle(Paint.Style.STROKE);mPaintCircle.setColor(Color.WHITE);mPaintDegree =
new Paint(Paint.ANTI_ALIAS_FLAG);mPaintDegree.setColor(Color.WHITE);mPaintDegree.setStrokeWidth(
3);mTimeHourPointPaint =
new Paint(Paint.ANTI_ALIAS_FLAG);mTimeHourPointPaint.setStrokeWidth(
20);mTimeMintuePointPaint =
new Paint(Paint.ANTI_ALIAS_FLAG);mTimeMintuePointPaint.setStrokeWidth(
10);
if (myThread ==
null) {startOpenThreadFlag =
true;myThread =
new Mythread();myThread.start();}}
@Overrideprotected void onDraw(Canvas canvas) {canvas.drawCircle(mCircleCenterX, mCircleCenterY, mCircleRadius, mPaintCircle);canvasDegree(canvas);canvasTimePoint(canvas);}
/*** 繪制時(shí)針;** @param canvas*/private void canvasTimePoint(Canvas canvas) {canvas.save();canvas.translate(mCircleCenterX, mCircleCenterY);canvas.drawLine(
0,
0,
120,
120, mTimeHourPointPaint);
float[] position = calculateMintuePosition(angle);canvas.drawLine(
0,
0, position[
0], position[
1], mTimeMintuePointPaint);canvas.restore();}
/*** 繪制刻度(表盤為例):*/private void canvasDegree(Canvas canvas) {canvas.save();
for (
int i =
0; i < mDegreeCount; i++) {
if (i ==
0 || i ==
6 || i ==
12 || i ==
18) {mPaintDegree.setStrokeWidth(
5);mPaintDegree.setTextSize(
40);canvas.drawLine(mCircleCenterX, mCircleCenterY - mCircleCenterX + padding, mCircleCenterX, mCircleCenterY - mCircleCenterX + padding + mTimeDegreeHourLength, mPaintDegree);String dergree = String.valueOf(i);canvas.drawText(dergree,mCircleCenterX - mPaintDegree.measureText(dergree) /
2,mCircleCenterY - mCircleCenterX + padding +
95,mPaintDegree);}
else {mPaintDegree.setStrokeWidth(
3);mPaintDegree.setTextSize(
20);canvas.drawLine(mCircleCenterX, mCircleCenterY - mCircleCenterX + padding, mCircleCenterX, mCircleCenterY - mCircleCenterX + padding + mTimeDegreeMintueLength, mPaintDegree);String dergree = String.valueOf(i);canvas.drawText(dergree,mCircleCenterX - mPaintDegree.measureText(dergree) /
2,mCircleCenterY - mCircleCenterX + padding +
60,mPaintDegree);}canvas.rotate(
360 / mDegreeCount, mCircleCenterX, mCircleCenterY);}}
@Overrideprotected void onMeasure(
int widthMeasureSpec,
int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);mCircleCenterX = getWidth() /
2;mCircleCenterY = getHeight() /
2;
if (mCircleCenterX > mCircleCenterY) {mCircleRadius = mCircleCenterY - padding;}
else {mCircleRadius = mCircleCenterX - padding;}mTimeHourLength = mCircleRadius -
2 * mTimeDegreeHourLength;mTimeMinuteLength = mCircleRadius -
2 * mTimeDegreeMintueLength;}
/*** 計(jì)算分針的坐標(biāo)。** @param angle* @return*/private float[]
calculateMintuePosition(
float angle) {
float x = (
float) (mTimeMinuteLength * Math.cos(Math.toRadians(angle)));
float y = (
float) (mTimeMinuteLength * Math.sin(Math.toRadians(angle)));
return new float[]{x, y};}
/*** 計(jì)算時(shí)針的坐標(biāo)。** @param angle* @return*/private float[]
calculateHourPosition(
float angle) {
float x = (
float) (mTimeHourLength * Math.cos(Math.toRadians(angle)));
float y = (
float) (mTimeHourLength * Math.sin(Math.toRadians(angle)));
return new float[]{x, y};}
@Overridepublic boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
float centerEventX = event.getX() - mCircleCenterX;
float centerEventY = event.getY() - mCircleCenterY;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:Log.d(TAG,
"eventX==" + eventX);Log.d(TAG,
"eventY==" + eventY);Log.d(TAG,
"centerEventX===================" + centerEventX);Log.d(TAG,
"centerEventY===================" + centerEventY);
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
break;}
return true;}
public class Mythread extends Thread {@Overridepublic void run() {
while (startOpenThreadFlag) {angle++;
if (angle ==
360) {angle =
0;}postInvalidate();
try {Thread.sleep(
1000);}
catch (InterruptedException e) {e.printStackTrace();}}}}
}
布局文件xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><com.example.xxx.myapplication.WatchView
android:layout_width="400dp"android:layout_height="400dp"android:layout_centerInParent="true"android:background="@color/colorWatch" /></RelativeLayout>
總結(jié)
以上是生活随笔為你收集整理的android studio 绘制时钟刻度表盘的虚拟动画。的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。