我正在设计一种新的转速表。我的旋转针有问题,我想按下按钮后针从o到1400。我试过,但我只能得到最后的价值而不是中间价值。如何使它工作?
package com.Jay.race;
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class Gag extends View {
private static final String TAG = "GMF";
public static float angle_of_deviation;
Gag speedo_obj;
private Handler handler;
// drawing tools
private RectF rimRect;
private Paint rimPaint;
private Paint rimCirclePaint;
private RectF faceRect;
private Bitmap faceTexture;
private Paint facePaint;
private Paint rimShadowPaint;
private Paint scalePaint;
private RectF scaleRect;
private Paint titlePaint;
private Path titlePath;
private Paint logoPaint;
private Bitmap logo;
private Matrix logoMatrix;
private float logoScale;
private Paint handPaint;
private Path handPath;
private Paint handScrewPaint;
private Paint backgroundPaint;
// end drawing tools
private Bitmap background; // holds the cached static part
// private Bitmap mFinalbitmap =
// BitmapFactory.decodeResource(getResources(), R.drawable.back);
// Scale configuration: totalNotches, centerValue, minScaleValue,
// maxScaleValue and
// scaleTitle can be given as property.
// It's better to call this notch i.s.o. nick. There is a saying...
// "Turn it up a notch"
private int totalNotches = 100;
private int incrementPerLargeNotch = 10;
private int incrementPerSmallNotch = 2;
private float degreesPerNotch = 360.0f / totalNotches;
private int cas = 0;
private int scaleCenterValue = 90; // the one in the top center (12 o'clock)
private int scaleMinValue = 0;
private int scaleMaxValue = 140;
private int scaleColor = 0x9f004d0f;
// hand dynamics -- all are angular expressed in F degrees
private boolean handInitialized = true;
private float handPosition = scaleMinValue;
private float handTarget = scaleCenterValue;
private float handVelocity = 0.0f;
private float handAcceleration = 0.0f;
private long lastHandMoveTime = -1L;
public Gag(Context context) {
super(context);
// TODO Auto-generated constructor stub
init(context, null);
}
public Gag(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public Gag(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
// TODO Auto-generated method stub
speedo_obj = this;
handler = new Handler();
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
// Get the properties from the resource file.
if (context != null && attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.Temperature);
totalNotches = a.getInt(R.styleable.Temperature_totalNotches,
totalNotches);
incrementPerLargeNotch = a.getInt(
R.styleable.Temperature_incrementPerLargeNotch,
incrementPerLargeNotch);
incrementPerSmallNotch = a.getInt(
R.styleable.Temperature_incrementPerSmallNotch,
incrementPerSmallNotch);
scaleCenterValue = a.getInt(
R.styleable.Temperature_scaleCenterValue, scaleCenterValue);
scaleMinValue = a.getInt(R.styleable.Temperature_scaleMinValue,
scaleMinValue);
scaleMaxValue = a.getInt(R.styleable.Temperature_scaleMaxValue,
scaleMaxValue);
scaleColor = a.getInt(R.styleable.Temperature_scaleColor,
scaleColor);
String scaleUpperTitle = a
.getString(R.styleable.Temperature_scaleUpperTitle);
String scaleLowerTitle = a
.getString(R.styleable.Temperature_scaleLowerTitle);
// if (scaleUpperTitle != null) this.scaleUpperTitle =
// scaleUpperTitle;
// if (scaleLowerTitle != null) this.scaleLowerTitle =
// scaleLowerTitle;
}
initdrawtools();
}
private void initdrawtools() {
rimRect = new RectF(0.1f, 0.1f, 0.9f, 0.9f);
// the linear gradient is a bit skewed for realism
rimPaint = new Paint();
rimPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
rimPaint.setShader(new LinearGradient(0.40f, 0.0f, 0.60f, 1.0f, Color
.rgb(0xf0, 0xf5, 0xf0), Color.rgb(0x30, 0x31, 0x30),
Shader.TileMode.CLAMP));
rimCirclePaint = new Paint();
rimCirclePaint.setAntiAlias(true);
rimCirclePaint.setStyle(Paint.Style.STROKE);
rimCirclePaint.setColor(Color.argb(0x4f, 0x33, 0x36, 0x33));
rimCirclePaint.setStrokeWidth(0.005f);
float rimSize = 0.02f;
faceRect = new RectF();
faceRect.set(rimRect.left + rimSize, rimRect.top + rimSize,
rimRect.right - rimSize, rimRect.bottom - rimSize);
faceTexture = BitmapFactory.decodeResource(getContext().getResources(),
R.drawable.plastic);
BitmapShader paperShader = new BitmapShader(faceTexture,
Shader.TileMode.MIRROR, Shader.TileMode.MIRROR);
Matrix paperMatrix = new Matrix();
facePaint = new Paint();
facePaint.setFilterBitmap(true);
paperMatrix.setScale(1.0f / faceTexture.getWidth(),
1.0f / faceTexture.getHeight());
paperShader.setLocalMatrix(paperMatrix);
facePaint.setStyle(Paint.Style.FILL);
facePaint.setShader(paperShader);
rimShadowPaint = new Paint();
rimShadowPaint.setShader(new RadialGradient(0.5f, 0.5f, faceRect
.width() / 2.0f,
new int[] { 0x00000000, 0x00000500, 0x50000500 }, new float[] {
0.96f, 0.96f, 0.99f }, Shader.TileMode.MIRROR));
rimShadowPaint.setStyle(Paint.Style.FILL);
scalePaint = new Paint();
scalePaint.setStyle(Paint.Style.STROKE);
scalePaint.setColor(scaleColor);
scalePaint.setStrokeWidth(0.005f);
scalePaint.setAntiAlias(true);
scalePaint.setTextSize(0.045f);
scalePaint.setTypeface(Typeface.SANS_SERIF);
scalePaint.setTextScaleX(0.8f);
scalePaint.setTextAlign(Paint.Align.CENTER);
// The scale rectangular is located .10 from the outer rim.
float scalePosition = 0.10f;
scaleRect = new RectF();
scaleRect.set(faceRect.left + scalePosition, faceRect.top
+ scalePosition, faceRect.right - scalePosition,
faceRect.bottom - scalePosition);
// The title rectangular is located .25 from the outer rim.
float titlePosition = 0.130f;
// titleRect = new RectF();
/*
* titleRect.set(faceRect.left + titlePosition, faceRect.top +
* titlePosition, faceRect.right - titlePosition, faceRect.bottom -
* titlePosition);
*/
titlePaint = new Paint();
titlePaint.setColor(0xaf946109);
titlePaint.setAntiAlias(true);
titlePaint.setTypeface(Typeface.DEFAULT_BOLD);
titlePaint.setTextAlign(Paint.Align.CENTER);
titlePaint.setTextSize(0.05f);
titlePaint.setTextScaleX(0.8f);
// titlePath = new Path();
// titlePath.addArc(new RectF(0.24f, 0.24f, 0.76f, 0.76f), -180.0f,
// -180.0f);
// Put the title in a rectangular and not as stated above. The code
// above is
// the original code and it is hard to maintain these values. Setting
// the start
// angle and sweep to a positive value causes the title to be displayed
// in the
// top half of the scale i.e.: titlePath.addArc(titleRect, 180.0f,
// 180.0f);
logoPaint = new Paint();
logoPaint.setFilterBitmap(true);
logo = BitmapFactory.decodeResource(getContext().getResources(),
R.drawable.logo);
logoMatrix = new Matrix();
logoScale = (1.0f / logo.getWidth()) * 0.3f;
;
logoMatrix.setScale(logoScale, logoScale);
handPaint = new Paint();
handPaint.setAntiAlias(true);
handPaint.setColor(0xff392f2c);
handPaint.setShadowLayer(0.01f, -0.005f, -0.005f, 0x7f000000);
handPaint.setStyle(Paint.Style.FILL);
// This code draws the hand with the tip facing north. When the hand is
// not rotated, it points to the center value.
handPath = new Path();
handPath.moveTo(0.5f, .5f + 0.05f);
handPath.lineTo(0.5f - 0.030f, 0.5f + 0.1f);
handPath.lineTo(0.5f - 0.002f, 0.5f - 0.32f);
handPath.lineTo(0.5f + 0.002f, 0.5f - 0.32f);
handPath.lineTo(0.5f + 0.030f, 0.5f + 0.1f);
handPath.lineTo(0.5f, 0.5f + 0.05f);
handPath.addCircle(0.5f, 0.5f, 0.035f, Path.Direction.CW);
handScrewPaint = new Paint();
handScrewPaint.setAntiAlias(true);
handScrewPaint.setColor(0xff493f3c);
handScrewPaint.setStyle(Paint.Style.FILL);
backgroundPaint = new Paint();
backgroundPaint.setFilterBitmap(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.d(TAG, "Width spec: " + MeasureSpec.toString(widthMeasureSpec));
Log.d(TAG, "Height spec: " + MeasureSpec.toString(heightMeasureSpec));
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int chosenWidth = chooseDimension(widthMode, widthSize);
int chosenHeight = chooseDimension(heightMode, heightSize);
int chosenDimension = Math.min(chosenWidth, chosenHeight);
setMeasuredDimension(chosenDimension, chosenDimension);
}
private int chooseDimension(int mode, int size) {
if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
return size;
} else { // (mode == MeasureSpec.UNSPECIFIED)
return getPreferredSize();
}
}
private int getPreferredSize() {
// TODO Auto-generated method stub
return 300;
}
@Override
protected void onDraw(Canvas canvas) {
// canvas.drawColor(Color.BLUE);
// canvas.drawBitmap(mFinalbitmap, 480, 690, null);
drawBackground(canvas);
float scale = (float) getWidth();
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.scale(scale, scale);
// drawLogo(canvas);
drawHand(canvas);
canvas.restore();
}
private void drawHand(Canvas canvas) {
// TODO Auto-generated method stub
canvas.drawPath(handPath, handPaint);
canvas.restore();
canvas.drawCircle(0.5f, 0.5f, 0.01f, handScrewPaint);
}
private float valueToAngle(float value) {
float fix = 0;
fix = (value - scaleCenterValue) / 2.0f * degreesPerNotch;
Log.d(TAG, "FIXXXX" + fix);
return fix;
}
private void drawBackground(Canvas canvas) {
// TODO Auto-generated method stub
if (background == null) {
Log.w(TAG, "Background not created");
} else {
canvas.drawBitmap(background, 0, 0, backgroundPaint);
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.d(TAG, "Size changed to " + w + "x" + h);
regenerateBackground();
}
private void regenerateBackground() {
// TODO Auto-generated method stub
// free the old bitmap
if (background != null) {
background.recycle();
}
background = Bitmap.createBitmap(getWidth(), getHeight(),
Bitmap.Config.ARGB_8888);
Canvas backgroundCanvas = new Canvas(background);
float scale = (float) getWidth();
backgroundCanvas.scale(scale, scale);
drawRim(backgroundCanvas);
drawFace(backgroundCanvas);
drawScale(backgroundCanvas);
}
private void drawScale(Canvas canvas) {
// TODO Auto-generated method stub
canvas.drawOval(scaleRect, scalePaint);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
for (int i = 0; i < totalNotches; ++i) {
float y1 = scaleRect.top;
float y2 = y1 - 0.015f;
float y3 = y1 - 0.025f;
int value = notchToValue(i);
if (i % (incrementPerLargeNotch / incrementPerSmallNotch) == 0) {
if (value >= scaleMinValue && value <= scaleMaxValue) {
// draw a nick
canvas.drawLine(0.5f, y1, 0.5f, y3, scalePaint);
String valueString = Integer.toString(value);
// Draw the text 0.15 away from y3 which is the long nick.
canvas.drawText(valueString, 0.5f, y3 - 0.015f, scalePaint);
}
} else {
if (value >= scaleMinValue && value <= scaleMaxValue) {
// draw a nick
canvas.drawLine(0.5f, y1, 0.5f, y2, scalePaint);
}
}
canvas.rotate(degreesPerNotch, 0.5f, 0.5f);
}
canvas.restore();
}
private int notchToValue(int value) {
int rawValue = ((value < totalNotches / 2) ? value
: (value - totalNotches)) * incrementPerSmallNotch;
int shiftedValue = rawValue + scaleCenterValue;
return shiftedValue;
}
private void drawFace(Canvas canvas) {
canvas.drawOval(faceRect, facePaint);
// draw the inner rim circle
canvas.drawOval(faceRect, rimCirclePaint);
// draw the rim shadow inside the face
canvas.drawOval(faceRect, rimShadowPaint);
}
private void drawRim(Canvas canvas) {
// TODO Auto-generated method stub
// first, draw the metallic body
canvas.drawOval(rimRect, rimPaint);
// now the outer rim circle
canvas.drawOval(rimRect, rimCirclePaint);
}
void moveHand(int tango) {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
for (int i = 0; i < 110; i++) {
handPosition = i;
Log.d(TAG, "I" + i);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
invalidate();
}
}
public void calculateAngleOfDeviation(int randomly_generated_value) {
// TODO Auto-generated method stub
Matrix mMatrix = new Matrix();
RectF bounds = new RectF();
handPath.computeBounds(bounds, true);
mMatrix.postRotate(valueToAngle(50), 0.5f, 0.5f);
handPath.transform(mMatrix);
speedo_obj.invalidate();
}
} `