custom view not align centre - android

i am drawing canavasarc but some how it always start from left i am it should start from middle
float x = 0.25f;
final float radius = x * (new Float(dpi));
mRadius = Math.round(radius) + 20;
mRect = new RectF(
getWidth() + mStrokeWidth, getWidth() + mStrokeWidth, getWidth() + (mRadius / 2) - mStrokeWidth, getWidth() + (mRadius / 2) - mStrokeWidth
);
canvas.drawArc(mRect, lastDegree, mSectionDegree, false, mPaint);
why this view always starts from left even i have given gravity centre still
float Degree = 270 + (mGap / 2);
for (int i = 0; i < mTotalSections; i++) {
fillColor(i);
canvas.drawArc(mRect, Degree, mDegree, false, mPaint);
Degree += mDegree + mGap;
Paint mPaint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint1.setStrokeWidth(1);
mPaint1.setStyle(Paint.Style.FILL);
mPaint1.setAntiAlias(true);
mPaint1.setTextSize(15 * getResources().getDisplayMetrics().density);
mPaint1.setColor(getResources().getColor(black));
mPaint1.setTextAlign(Paint.Align.CENTER);
canvas.drawText(text, mRect.centerX(), mRect.centerY(), mPaint1);
}

I'm not sure about what you want to do but your rect looks weird. A rect more like that should would be better:
mRect = new RectF(
0 + mStrokeWidth, 0 + mStrokeWidth, getWidth() - mStrokeWidth, getHeight - mStrokeWidth
);
But a little draw about what you want and the values of your angle would be perfect ;). I will edit my answer if you provide it.
Edit:
So if you want a circle in the middle of your custom view you can do something like that:
RectF mRect = new RectF(
50 + mStrokeWidth, 50 + mStrokeWidth, getWidth() -50 - mStrokeWidth, getHeight() -50 - mStrokeWidth
);
canvas.drawArc(mRect, 0,360,false,paint);
result(the blue lines are the limit of my view):
You have to modify the 50 to fit what you want ;).
If you want an arc that stick to the edges with an angle of 180 degrees:
RectF mRect = new RectF(
mStrokeWidth, mStrokeWidth, getWidth() - mStrokeWidth, getHeight() - mStrokeWidth
);
canvas.drawArc(mRect, 0,180,false,paint);
Result:
Let me know if you need something else.

Related

android canvas animate background?

I'm trying to animate a background in a game I'm making.
https://imgur.com/kQGWsLu
Should look like this(terrible recording quality)
My first attempt work well on my phone but a lot of people saw their fps cut in half:
public void draw(Canvas canvas, Paint paint) {
if (mPaint == null) {
mPaint = new Paint();
mPaint.setColor(Color.GRAY);
mPaint.setStrokeWidth(1);
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setShader(new RadialGradient(canvas.getWidth() / 4, canvas.getHeight() / 3,
Math.max(1, canvas.getHeight() / 2), Color.rgb(5, 12, 127), Color.rgb(32, 36, 100), Shader.TileMode.REPEAT));
}
width = canvas.getWidth();
height = canvas.getHeight();
canvas.save();
rotation += 4;
if (rotation > 360)
rotation = 0;
canvas.rotate(rotation, width / 2, height / 2);
canvas.drawCircle(width / 2, height / 2, height * 1.3f, mPaint);
canvas.restore();
}
So now I'm thinking about of pre rendering a image and drawing it as a bitmap that covers the screen and rotates instead. I also cut the calculations to only update every other frame instead.
public void draw(Canvas canvas, Paint paint) {
if (!initiated) {
centerX = (int) (canvas.getWidth() / 2);
centerY = (int) (canvas.getHeight() / 2);
width = (int) (canvas.getWidth() * 2f);
height = (int) (canvas.getHeight() * 2f);
map = factory.GFX().getBackground();
initiated = true;
}
if (!skipUpdate) {
x = CalculatorService.getXCircle(rotation, distance, centerX);
y = CalculatorService.getYCircle(rotation, distance, centerY);
body.set((int) x - width / 2,
(int) y - height / 2,
(int) x + (width / 2),
(int) y + (height / 2));
rotation += rotationSpeed;
if (rotation > 360)
rotation = 0;
}
skipUpdate = !skipUpdate;
canvas.drawBitmap(map, null, body, paint);
}
Though since the image is small in size 320*320 I had to scale it up and draw it bigger then the screen to avoid it moving out of bounds and showing the basic black background, and I'm not sure if this is really a improvement, do anyone have a better way of doing it or any advice on how I can improve?

How to get text BaseLine from Paint

I am trying to draw a text at the centre of canvas, Since canvas starts drawing text at BaseLine, I am not able to Place it at centre. If i can get the baseLine, then i can calculate the centre.
I have tried with paint.getFontMetrics() this gives ascent and descent but not baseLine.
Did you try this code
private void drawCenter(Canvas canvas, Paint paint, String text) {
canvas.getClipBounds(r);
int cHeight = r.height();
int cWidth = r.width();
paint.setTextAlign(Paint.Align.LEFT);
paint.getTextBounds(text, 0, text.length(), r);
float x = cWidth / 2f - r.width() / 2f - r.left;
float y = cHeight / 2f + r.height() / 2f - r.bottom;
canvas.drawText(text, x, y, paint);
}
All the calculations of paint.getFontMetrics() will happen with respect to baseLine. So if i just subtract (getMeasuredHeight() / 2f) - (fontMetrics.ascent / 2f) it will draw from center

Draw circle on start and end point of an Arc

Hi im having difficulties on drawing dots on arc's both ends (start and end)
Although I can draw arc on canvas. Heres my sample code for drawing arc.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
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;
final RectF oval = new RectF();
center_x = width / 2;
center_y = height / 2;
oval.set(center_x - radius,
center_y - radius,
center_x + radius,
center_y + radius);
float percent = 25;
float arcRadius = 360;
float angle = arcRadius * (percent/100);
canvas.drawArc(oval, 270, 360, false, trackpaint);
canvas.drawArc(oval, 270, angle, false, arcPaint);
}
the only missing is putting circles on start and end points of the arc. I've tried this link but it doest work Calculate Arc Center Point, Knowing It's Start and End Degrees. Any help will be much appreciated. Thank you
the coordinate of the start point is:
double startX = Math.cos(Math.toRadians(270)) * radius + center_x;
double startY = Math.sin(Math.toRadians(270)) * radius + center_y;
the coordinate of the end point is:
double endX = Math.cos(Math.toRadians(270 + angle)) * radius + center_x;
double endY = Math.sin(Math.toRadians(270 + angle)) * radius + center_y;
and then you can draw circle using the start point and end point:
canvas.drawCircle(startX, startY, 10, paint);
canvas.drawCircle(endX, endY, 10, paint);
Get path from the ARC
Use PathMeasure class to retrieve Path length and path TAN, using starting or Ending X and Y coordinates of the ARC
Use this X and Y coordinates to draw circle.
Example for circle at the start of the ARC:
final Path mPath = new Path();
mPath.addArc(oval, startAngle, sweepAngle);
PathMeasure pm = new PathMeasure(mPath, false);
float[] xyCoordinate = { arcStarting.x , arcStarting.y };
float pathLength = pm.getLength();
pm.getPosTan(0, xyCoordinate, null);//"0 for starting point"
PointF point = new PointF(xyCoordinate[0], xyCoordinate[1]);
canvas.drawCircle(point.x, point.y, 10, YourPaintHere)

how to rotate different part of canvas separately in android

i have custom view that contains many rectangles and ovals and ..... i can rotate my whole canvas(rect and ovals and ....) by using canvas.Rotate(degree,cneterX,centerY)
but in bottom of the my view i want to have a something like menu that doesn't rotate when i use canvas.rotate() . it means that i want to rotate these rectangles and ovals but don't wanna rotate my menu that will be create with same canvas.
#Override
protected void onDraw(Canvas canvas) {
float ringWidth = textHeight + 4;
int height = getMeasuredHeight();
int width =getMeasuredWidth();
int px = width;
int py = height/2;
Point center = new Point(px,py );
int radius = Math.max(px, py)-2;
int UpperSide = center.y;
RectF boundingBox = new RectF(center.x - radius, center.y - radius, center.x + radius, center.y + radius);
RectF innerBoundingBox = new RectF(center.x - radius , center.y - radius , center.x + radius, center.y + radius );
RectF GroundSectionBox = new RectF(center.x - radius,UpperSide ,center.x + radius,center.y + radius);
RectF RightPanel = new RectF(center.x + width -(width/4), center.y - (radius/2)+10, center.x+radius- ringWidth, center.y + (radius/2)-10);
RectF LeftPanel = new RectF(center.x - radius + ringWidth ,center.y - (radius/2)+10, center.x - width + (width/4), center.y + (radius/2)-10);
RectF RightBlack = new RectF(center.x + width -(width/4),center.y-(radius/10),center.x+radius- ringWidth,center.y + (radius/10));
RectF leftBlack = new RectF(center.x - radius + ringWidth ,center.y - (radius/10), center.x - width + (width/4), center.y + (radius/10));
.
.
canvas.drawRect(innerBoundingBox, groundPaint);
canvas.drawPath(skyPath, skyPaint);
canvas.drawRect(GroundSectionBox, skyPaint);
canvas.drawPath(skyPath, markerPaint);
canvas.drawRect(RightBlack, sideBlack);
canvas.drawRect(leftBlack, sideBlack);
canvas.drawRect(RightPanel, RightPanelup);
canvas.drawRect(LeftPanel, LeftPanelUp);
.
.
}
You cans use the save and restore methods on Canvas to draw stuff in transformations, then restore back to the original state. Here's an example:
protected void onDraw(Canvas canvas)
{
canvas.save(); // Canvas is in original state. Save it before anything
// Perform any transformations you want here (like rotate)
// Draw while your transformations are in place (like ovals)
canvas.restore(); // Canvas state returned to what it was when you called save
// Draw things that need to be drawn without any transformations
}
Hope this helps :)

Canvas.drawArc() doesn't draw anything

I'm trying to draw an arc to overlay on top of some part of an existing circle. Both of my circles draw perfectly fine, but neither my drawArc() call or my drawRect() call seem to do anything. The app does not crash, there is no exception. It just fails silently.
onDraw() code:
#Override
protected void onDraw(Canvas canvas) {
int width = getWidth();
int height = getHeight();
int size = (width > height) ? height : width;
float cx = width / 2;
float cy = height / 2;
float radius = size / 2;
float left = cx - radius;
float right = cx + radius;
float top = cy - radius;
float bottom = cy + radius;
RectF rect = new RectF(left, top, right, bottom);
RectF rect2 = new RectF(canvas.getClipBounds());
Log.d("MyTag", "Left: " + rect.left + "Right: " + rect.right + "Top: " + rect.top + "Bottom: " + rect.bottom);
Log.d("MyTag", "Left: " + rect2.left + "Right: " + rect2.right + "Top: " + rect2.top + "Bottom: "
+ rect2.bottom);
canvas.drawCircle(cx, cy, radius, circleRing);//Works
canvas.drawCircle(cx, cy, radius - barWidth, innerColor);//Works
canvas.drawArc(rect, 0, angle, true, circleColor);//Doesn't work
canvas.drawRect(rect, circleColor);//Doesn't work
super.onDraw(canvas);
}
I have confirmed that my circleColor Paint is properly setup, and that angle is a valid value for an arc.
My paints are setup as follows in a {} block so that all constructors use it:
{
circleColor = new Paint();
innerColor = new Paint();
circleRing = new Paint();
circleColor.setColor(color.holo_blue_light);
innerColor.setColor(Color.BLACK);
circleRing.setColor(Color.GRAY);
circleColor.setAntiAlias(true);
innerColor.setAntiAlias(true);
circleRing.setAntiAlias(true);
circleColor.setStrokeWidth(50);
innerColor.setStrokeWidth(5);
circleRing.setStrokeWidth(5);
circleColor.setStyle(Paint.Style.FILL);
}
What I have tried:
Hardcoding coordinates
Using the paints used by the circles
Having only the drawArc() call present and commenting out the rest of the draws
Disabling hardware acceleration
The Logcat shows that my RectF has valid points, just top and bottom scaled to form a square:
01-25 13:33:39.877: D/MyTag(21612): Left: 0.0 Right: 720.0 Top: 159.0 Bottom: 879.0 //Mine
01-25 13:33:39.877: D/MyTag(21612): Left: 0.0 Right: 720.0 Top: 0.0 Bottom: 1038.0 //Canvas'
Does anybody know what could be causing this?
Turns out the problem was the line
circleColor.setColor(color.holo_blue_light);
While the Android SDK defines this as:
A light Holo shade of blue
Constant Value: 17170450 (0x01060012)
It doesn't seem to be a valid color as far as my Canvas is concerned (note that this was added in API 14, and I'm testing on Android 4.2 so it should be available to me). However, changing it to use a more... normal color works fine:
circleColor.setColor(Color.GREEN);

Categories

Resources