转载请标明出处:
http://blog.csdn.net/liuzg1220;
本文出自:【HugeBug的博客】
时如白驹过隙,稍动即失!转眼间已经入行很多年,然而在这些年里,看了很多大神的博客,也从中学到很多,同时也结交了很多朋友。在这里首先我带着我这颗感恩的心,感谢csdn给"IT攻城狮们"提供了这么好的一个交流分享的平台。
扯了这么多的蛋,还是直接进入主题吧:先看效果图
OK,看完效果图,我们做个简单的分析,首先能够让中间的指针旋转起来,其次要真确的反应当前的测试的网速,说到这里大家肯定都会想到自定义View,并且在自定义View里绘制两个图层。废话不多说直接上代码:
package com.lzg.speedmeter.view;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import com.lzg.speedmeter.R;
/**
* test neetspeed
*
* @author lzg
*
*/
public class TestNeetSpeedView extends View {
/**
* 每一档表示的网络速度值:Kb
*/
private final int ZORE = 0;
private final int FIRST_STALL = 256;
private final int SECOND_STALL = 512;
private final int THIRD_STALL = 1028;
private final int FOURTH_STALL = 2048;
private final int FIFTH_STALL = 5120;
private final int SIXTH_STALL = 10240;
private final int SEVENTH_STALL = 20480;
private final int EIGHTH_STALL = 51200;
private final int NINTH_STALL = 102400;
private final int TENTH_STALL = 204800;
/**
* 每一档之间的角度
*/
private final int STEP_DEGREE = 30;
/**
* 指针旋转时步进频率
*/
private final int ALL_STEPS = 30;
/**
* 实例化一个Paint并且指定为抗锯齿
*/
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
// 旋转的度数
private double mDegrees = 0;
// private Matrix mMatrix = new Matrix();
/**
* 网速
*/
private Double neetSpeed;
private Bitmap auto_pointer;// 指针
private Bitmap auto_dashdoard;// 刻度面板
private double stepValue;// 步进度数
private double dstDegrees;// 目标度数
private boolean getDst = false;// 到达目标值的信号
private Context context;
/**
* 仪表盘一半的宽度值
*/
private float dashdoardWithHalf;
/** The width of the view */
/** view的宽 */
private int width;
/** The height of the view */
/** view的高 */
private int height;
/** The circle's center X coordinate of Matrix */
/** 指针旋转的中心点x坐标 */
private float cx;
/** The circle's center Y coordinate of Matrix */
/** 指针旋转的中心点y坐标 */
private float cy;
/** The left bound for the circle RectF */
/** 图层左边X坐标 */
private float left;
/** 图层上边Y坐标 */
private float right;
/** 图层右边X坐标 */
private float top;
/** 图层底边边Y坐标 */
private float bottom;
/**
* 表盘图层
*/
private RectF dashRectF = new RectF();
/**
* 指针图层
*/
private RectF pointRectF = new RectF();
public TestNeetSpeedView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setFocusable(true);
setFocusableInTouchMode(true);
this.context = context;
mPaint.setAntiAlias(true);
initDrawable();
}
public TestNeetSpeedView(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
setFocusableInTouchMode(true);
this.context = context;
mPaint.setAntiAlias(true);
initDrawable();
}
public TestNeetSpeedView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.context = context;
mPaint.setAntiAlias(true);
initDrawable();
}
/**
* 初始化表盘和指针的图片
*/
private void initDrawable() {
auto_dashdoard = BitmapFactory.decodeResource(context.getResources(),
R.drawable.labe_bak);
auto_pointer = BitmapFactory.decodeResource(context.getResources(),
R.drawable.point_bak);
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.argb(0, 0, 0, 0));
drawDashdoard(canvas);
drawPoint(canvas);
super.onDraw(canvas);
}
/**
* 绘制仪表盘
*
* @param canvas
*/
private void drawDashdoard(Canvas canvas) {
/*
* 保证刻度图剧中
*/
canvas.drawBitmap(auto_dashdoard, null, dashRectF, mPaint);
}
/**
* 绘制指针
*
* @param canvas
*/
private void drawPoint(Canvas canvas) {
/*
* 设置选择角度
*/
canvas.rotate((float) mDegrees, cx, cy);
/**
* 绘制指针
*/
canvas.drawBitmap(auto_pointer, null, pointRectF, mPaint);
if (!getDst)
// 获取每次步进的度数
stepValue = (dstDegrees - mDegrees) / ALL_STEPS;
// 正时针旋转
if (stepValue > ZORE && !getDst) {
if (mDegrees < dstDegrees) {
mDegrees = mDegrees + 4 * stepValue;
getDst = false;
}
if (mDegrees >= dstDegrees - 0.1) {
mDegrees = dstDegrees;
getDst = true;
stepValue = 0;
}
}
// 逆时针旋转
if (stepValue < ZORE && !getDst) {
if (mDegrees > dstDegrees) {
mDegrees = mDegrees + 4 * stepValue;
getDst = false;
}
if (mDegrees <= dstDegrees + 0.1) {
mDegrees = dstDegrees;
getDst = true;
stepValue = 0;
}
}
// 到达目标值之后回零
if (getDst) {
if (mDegrees > 0) {
mDegrees -= 1;
}
if (mDegrees <= 0) {
mDegrees = 0;
dstDegrees = 0;
getDst = false;
}
}
invalidate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getWidth(); // Get View Width
height = getHeight();// Get View Height
int size = (width > height) ? height : width; // Choose the smaller
dashdoardWithHalf = size / 2 * 100 / 100;
cx = width / 2;
cy = height / 2;
left = cx - dashdoardWithHalf;
right = cx + dashdoardWithHalf;
top = cy - dashdoardWithHalf;
bottom = cy + dashdoardWithHalf;
dashRectF.set(left, top, right, bottom);
pointRectF.set(left, top, right, bottom);
}
/**
* 设置网速
*
* @param neetSpeed
*/
public void setNeetSpeed(Double neetSpeed) {
this.getDst = false;
this.neetSpeed = neetSpeed;
this.dstDegrees = getDstDegreesByNeetSeep();
}
/**
* 根据网速获取旋转角度
*
* @return
*/
private double getDstDegreesByNeetSeep() {
Double dstDegree = 0d;
if (neetSpeed >= ZORE && neetSpeed < FIRST_STALL) {
dstDegree = neetSpeed * STEP_DEGREE / FIRST_STALL;
} else if (neetSpeed >= FIRST_STALL && neetSpeed < SECOND_STALL) {
dstDegree = STEP_DEGREE + (neetSpeed - FIRST_STALL) * STEP_DEGREE
/ (SECOND_STALL - FIRST_STALL);
} else if (neetSpeed >= SECOND_STALL && neetSpeed < THIRD_STALL) {
dstDegree = 2 * STEP_DEGREE + (neetSpeed - SECOND_STALL)
* STEP_DEGREE / (THIRD_STALL - SECOND_STALL);
} else if (neetSpeed >= THIRD_STALL && neetSpeed < FOURTH_STALL) {
dstDegree = 3 * STEP_DEGREE + (neetSpeed - THIRD_STALL)
* STEP_DEGREE / (FOURTH_STALL - THIRD_STALL);
} else if (neetSpeed >= FOURTH_STALL && neetSpeed < FIFTH_STALL) {
dstDegree = 4 * STEP_DEGREE + (neetSpeed - FOURTH_STALL)
* STEP_DEGREE / (FIFTH_STALL - FOURTH_STALL);
} else if (neetSpeed >= FIFTH_STALL && neetSpeed < SIXTH_STALL) {
dstDegree = 5 * STEP_DEGREE + (neetSpeed - FIFTH_STALL)
* STEP_DEGREE / (SIXTH_STALL - FIFTH_STALL);
} else if (neetSpeed >= SIXTH_STALL && neetSpeed < SEVENTH_STALL) {
dstDegree = 6 * STEP_DEGREE + (neetSpeed - SIXTH_STALL)
* STEP_DEGREE / (SEVENTH_STALL - SIXTH_STALL);
} else if (neetSpeed >= SEVENTH_STALL && neetSpeed < EIGHTH_STALL) {
dstDegree = 7 * STEP_DEGREE + (neetSpeed - SEVENTH_STALL)
* STEP_DEGREE / (EIGHTH_STALL - SEVENTH_STALL);
} else if (neetSpeed >= EIGHTH_STALL && neetSpeed < NINTH_STALL) {
dstDegree = 8 * STEP_DEGREE + (neetSpeed - EIGHTH_STALL)
* STEP_DEGREE / (NINTH_STALL - EIGHTH_STALL);
} else if (neetSpeed >= NINTH_STALL && neetSpeed <= TENTH_STALL) {
dstDegree = 9 * STEP_DEGREE + (neetSpeed - NINTH_STALL)
* STEP_DEGREE / (TENTH_STALL - NINTH_STALL);
} else {
dstDegree = 10d * STEP_DEGREE;
}
return dstDegree;
}
}
以上就是自定义View的代码,接下来就是在layout中直接使用自定义的view就可以了。具体实现请下载详细代码。
如果你觉得有用就关注我吧,在这里将不定期的发表原创文章!如果你觉得有用就留个言,点个赞吧!
下面是我微信公众号:如果你喜欢就扫扫看吧!