addressalign-toparrow-leftarrow-leftarrow-right-10x10arrow-rightbackbellblockcalendarcameraccwcheckchevron-downchevron-leftchevron-rightchevron-small-downchevron-small-leftchevron-small-rightchevron-small-upchevron-upcircle-with-checkcircle-with-crosscircle-with-pluscontroller-playcredit-cardcrossdots-three-verticaleditemptyheartexporteye-with-lineeyefacebookfolderfullheartglobe--smallglobegmailgooglegroupshelp-with-circleimageimagesinstagramFill 1languagelaunch-new-window--smalllight-bulblightning-boltlinklocation-pinlockm-swarmSearchmailmediummessagesminusmobilemoremuplabelShape 3 + Rectangle 1ShapeoutlookpersonJoin Group on CardStartprice-ribbonprintShapeShapeShapeShapeImported LayersImported LayersImported Layersshieldstar-shapestartickettrashtriangle-downtriangle-uptwitteruserwarningyahooyoutube

[blrdroid] [blrdroid][question] : Trying to create custom speedometer but stuck at some places

From: harish
Sent on: Wednesday, January 6, 2016, 4:00 PM
Hi Droids,

I'm trying to create Speedometer as shown in the attachment.Below is the code what i have tried ..

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.RectF;
import android.graphics.Shader;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.View;


public class SpeedometerView extends View {
private Paint backgroundPaint;
private Paint ticksPaint;
private Paint needlePaint;

public static final double DEFAULT_MAX_SPEED = 100.0;
public static final double DEFAULT_MAJOR_TICK_STEP = 5.0;
public static final int DEFAULT_MINOR_TICKS = 4;

private double maxSpeed = DEFAULT_MAX_SPEED;
private int defaultColor;
private double majorTickStep = DEFAULT_MAJOR_TICK_STEP;
private int minorTicks = DEFAULT_MINOR_TICKS;

public SpeedometerView(Context context) {
super(context);

}

public SpeedometerView(Context context, AttributeSet attrs) {
super(context, attrs);
}

private void init() {
defaultColor = ContextCompat.getColor(getContext(),R.color.orange);
backgroundPaint = new Paint();
backgroundPaint.setStyle(Paint.Style.STROKE);
backgroundPaint.setColor(defaultColor);
backgroundPaint.setStrokeWidth(150);

needlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
needlePaint.setStrokeWidth(5);
needlePaint.setStyle(Paint.Style.STROKE);
needlePaint.setAntiAlias(true);
needlePaint.setShader(new RadialGradient(130.0f, 50.0f, 10.0f,
Color.DKGRAY, Color.BLACK, Shader.TileMode.CLAMP));

ticksPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
ticksPaint.setStrokeWidth(3);
ticksPaint.setStyle(Paint.Style.STROKE);
defaultColor = ContextCompat.getColor(getContext(),R.color.black);
ticksPaint.setColor(defaultColor);


}

@Override

protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
init();
drawBackground(canvas);
drawTicks(canvas);
drawNeedle(canvas);
}

private RectF getOval() {
RectF oval;
float width = (float) getWidth();
float height = (float) getHeight();
float radius;
if (width > height) {
radius = height / 4;
} else {
radius = width / 4;
}
float center_x, center_y;

center_x = width / 2;

center_y = height / 4;

oval = new RectF();

oval.set(center_x - radius, center_y - radius, center_x + radius, center_y + radius);

return oval;
}

private void drawBackground(Canvas canvas) {
RectF oval = getOval();
backgroundPaint.setColor(ContextCompat.getColor(getContext(), R.color.orange));
canvas.drawArc(oval, 180, 180, false, backgroundPaint);

backgroundPaint.setColor(ContextCompat.getColor(getContext(),R.color.green));
canvas.drawArc(oval, 180, 43, false, backgroundPaint);

}

private void drawTicks(Canvas canvas) {
float availableAngle = 160;
float majorStep = (float) (majorTickStep / maxSpeed * availableAngle);
float minorStep = majorStep / (1 + minorTicks);

float majorTicksLength = 25;
float minorTicksLength = majorTicksLength / 2;

RectF oval = getOval();
float radius = oval.width() * 0.60f;

float currentAngle = 10;
double curProgress = 0;
while (currentAngle <= 170) {

canvas.drawLine(
(float) (oval.centerX() + Math.cos((180 - currentAngle) / 180 * Math.PI) * (radius - majorTicksLength / 2)),
(float) (oval.centerY() - Math.sin(currentAngle / 180 * Math.PI) * (radius - majorTicksLength / 2)),
(float) (oval.centerX() + Math.cos((180 - currentAngle) / 180 * Math.PI) * (radius + majorTicksLength / 2)),
(float) (oval.centerY() - Math.sin(currentAngle / 180 * Math.PI) * (radius + majorTicksLength / 2)),
ticksPaint
);

for (int i = 1; i <= minorTicks; i++) {
float angle = currentAngle + i * minorStep;
if (angle >= 170 + minorStep / 2) {
break;
}
canvas.drawLine(
(float) (oval.centerX() + Math.cos((180 - angle) / 180 * Math.PI) * radius),
(float) (oval.centerY() - Math.sin(angle / 180 * Math.PI) * radius),
(float) (oval.centerX() + Math.cos((180 - angle) / 180 * Math.PI) * (radius + minorTicksLength)),
(float) (oval.centerY() - Math.sin(angle / 180 * Math.PI) * (radius + minorTicksLength)),
ticksPaint
);
}


currentAngle += majorStep;
curProgress += majorTickStep;
}
}

private void drawNeedle(Canvas canvas) {
RectF oval = getOval();
float radius = oval.width() * 0.05f;
RectF smallOval = getOval();

float angle = 43;

canvas.drawLine(
(float) (oval.centerX() + Math.cos((180 - angle) / 180 * Math.PI) * smallOval.width() * 0.5f),
(float) (oval.centerY() - Math.sin(angle / 180 * Math.PI) * smallOval.width() * 0.5f),
(float) (oval.centerX() + Math.cos((180 - angle) / 180 * Math.PI) * (radius)),
(float) (oval.centerY() - Math.sin(angle / 180 * Math.PI) * (radius)),
needlePaint);


}
}

with the above code i'm getting the view but it is occupying the entire layout i need to fit it where ever i need.And with my above code needle is also not that much perfect which i need.And i also need rotating animation for the needle and green color according to the value changes.Droids please guide me to achieve this as i'm new to the canvas.

Thanks
Harish 

This email message originally included an attachment.

People in this
group are also in: