I have looked all over, but nothing has worked. Every time I try finding the center of the screen for my watch face, it always end up slightly higher than the center, and to the far right of the screen (This is different than the problem that the original template from Android Studio has, where the Watch face is slightly up and all the way to the far left of the screen). What could I be doing wrong?
(First screenshot on Left: My problem. Second screenshot: Original form of the Android Wear template from Android Studio)
#Override
public void onDraw(Canvas canvas, Rect bounds) {
if (isInAmbientMode()) {canvas.drawColor(Color.BLACK);
}
else {
canvas.drawRect(0, 0, bounds.width(), bounds.height(), mBackgroundPaint);
}
// Draw H:MM in ambient mode or H:MM:SS in interactive mode.
long now = System.currentTimeMillis();
mCalendar.setTimeInMillis(now);
int width = bounds.width();
int height = bounds.height();
float centerX = width / 2f;
float centerY = height / 2f;
String text = mAmbient
? String.format("%d:%02d", mCalendar.get(Calendar.HOUR),
mCalendar.get(Calendar.MINUTE))
: String.format("%d:%02d", mCalendar.get(Calendar.HOUR),
mCalendar.get(Calendar.MINUTE));
canvas.drawText(text, centerX, centerY, mTextPaint);
}
Full code can be found here
As far as i can tell from a quick look on your sources you already calculate mTextXOffset and mTextYOffset but don't use it for your draw call, hence the texts origin is centered in your problematic screenshot instead of the texts center.
adjusting your centerX and centerY by mTextXOffset and mTextYOffset should do the trick.
If you're drawing text using a center point you can use
mTextPaint.setTextAlign(Paint.Align.CENTER);
which will draw from the center. Otherwise the x coordinte represents the left hand side of the text you are drawing.
Related
I have a code to scale drawing canvas.
So i tried this code. i scale it but it moves down,
here is my code:
canvas.save();
scaleA = 1.1;
scaleB = 1.1;
canvas.scale(scaleA, scaleB);
canvas.restore();
the issue is even when i scale the Y coordinates move down, so i try to translate or reduce y coordinates but i still issue. any one knows how to properly scale a drawing canvas?
i tried like this:
canvas.save();
scaleA = 1.1;
scaleB = 1.1;
canvas.translate(scaleA, -scaleB);
canvas.scale(scaleA, scaleB);
canvas.restore();
You have to set the center of your image, if your image center is equal to the canvas(view) center
canvas.scale(sx, sy, canvas.getWidth() / 2, canvas.getHeight() / 2);
Or else, change the last two params to whatever center you want it to be, you don't need to translate
I have a virtual ruler being drawn on the screen. I want to be able to draw a straight line like the blue line above when touch event happen within the grown rectangle. but because touch can't be 100% straight, the movement might be like the red line. that's why I set a rectangle to listen to all the nearby touch events then draw a blue line.
I currently have
mRulerRect.set(mRulerCenter.x - mRulerBitmap.getWidth() / 2,
mRulerCenter.y - mRulerBitmap.getHeight()),
mRulerCenter.x + mRulerBitmap.getWidth() / 2,
mRulerCenter.y);
mPath.addRect(mRulerRect, Path.Direction.CCW);
mRulerMatrix.setRotate(mRulerAngle, mRulerCenter.x, mRulerCenter.y);
mPath.transform(mRulerMatrix);
mRegions.setPath(mPath, new Region(mRulerRect));
then I check if the touch even happen within brown rectangle by mRegions.contains(x,y). works perfect so far for touch detection, but the problem I have now is how to draw a straight line. I tried to fix X point then calculate Y. it works fine when ruler is horizontal then starts to behave very weird when turning from horizontal to vertical. I'm out of idea how to accomplish this. Please help! thank you.
Things that you know:
The center of that brown rect is mRulerCenter.x, mRulerCenter.y
The line that you want to draw pass through that point
The angle of the line is mRulerAngle
We're missing just one element, which is, the length of the line we want to draw. That's probably going to be a portion of the ruler's width and it should be very easy to compute mRulerRect.width() * someFactor
Now, we want to know what are the start and the end of the line, we can compute that with trigonometry functions
float halfLineLength = mRulerRect.width() * someFactor;
float startAngle = (float) Math.toRadians(mRulerAngle);
float endAngle = (float) Math.toRadians(mRulerAngle + 180);
float startX = mRulerCenter.x + (float) Math.cos(startAngle) * halfLineLength;
float startY = mRulerCenter.y + (float) Math.sin(startAngle) * halfLineLength;
float endX = mRulerCenter.x + (float) Math.cos(endAngle) * halfLineLength;
float endY = mRulerCenter.y + (float) Math.sin(endAngle) * halfLineLength;
and then draw your line from (startX, startY) to (endX, endY), actually doesn't really matter which is start and which is end
I am new to android watch face development and facing some problem with alignment of time text! I am displaying time in two format, How can I display it one at top and one at bottom and center aligned as shown in image below? Is there any pattern or layout for this?
It's up to you to figure out the alignment yourself when calling Canvas.drawText in your onDraw handler. I use code something like this:
String msg = "Text to display";
float width = paint.measureText(msg);
canvas.drawText(msg, centerX - width / 2f, top, paint);
where paint, top, and centerX were all initialized previously. The first two will depend on your face design, while the third is a Point field that can be set in your onCreate handler like so:
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
display.getSize(displaySize);
centerX = displaySize.x / 2f;
Alternately, you could do all of this in XML with a layout-based watch face, but this may or may not be a good fit for your needs.
I am using the sample second, hour, and minute ticker/clock hands for a sample watch face on Android Studio. There, draw line method of Canvas class is being used with a startX, startY, stopX, and stopY. My question is how do I implement this similarly using a picture? I thought of using drawBitmap which only has a left and top and so it rotates but way too widely and not in place as the hands do.
Is there any way to use an image instead of a line like in the drawLine method? The bottom line is that I need to use an image instead of a line as a clock hand.
Thanks!
You should use Canvas.save, Canvas.rotate and Canvas.restore. Imagine, that you always draw things in the same place, but the underlying canvas is being rotated, so you will draw in the right place. Consider the example from the Santa Tracker:
for (int i = 0; i < mCloudBitmaps.length; i++) {
canvas.save();
canvas.rotate(mCloudDegrees[i], centerX, centerY);
float r = centerX - (timeElapsed / (mCloudSpeeds[i])) % centerX;
mCloudFilterPaints[i].setAlpha((int) (r / centerX * 255));
canvas.drawBitmap(mCloudBitmaps[i], centerX, centerY - r,
mCloudFilterPaints[i]);
canvas.restore();
}
It doesn't draw hands, but instead the clouds on the watch face, but it should give you an example of what you need to try to do.
Here is the situation. I am rendering to a canvas. Nothing else is being rendered, the canvas is effectively fullscreen. There is only one view.
I want to make a simple (text) button. This consists of two parts: visually drawing it, and checking bounds to see if it is pressed. These two things should be consistent.
Ideally the centering is optional, though I would expect switching it to be simple.
After far too many hours, I suspect it is not simply an alignment issue, but also a use of the API that is the source of the problem.
How can this be done?
Just use static layouts and then you can keep the text center aligned inside the canvas even if the size is increased by some limit by auto aligning the text.
Rect bounds = new Rect(x1, y1, x2, y2);// set the bounds
String textOnCanvas = "text to be wriiten";
StaticLayout sl = new StaticLayout(textOnCanvas, textPaint,
bounds.width(), Layout.Alignment.ALIGN_CENTER, 1, 1, true);
canvas.save();
float textHeight = getTextHeight(textOnCanvas, textPaint);
int numberOfTextLines = sl.getLineCount();
float textYCoordinate = bounds.exactCenterY() -
((numberOfTextLines * textHeight) / 2);
//text will be drawn from left
float textXCoordinate = bounds.left;
canvas.translate(textXCoordinate, textYCoordinate);
//draws static layout on canvas
sl.draw(canvas);
canvas.restore();
The parameter Layout.Alignment.ALIGN_CENTER of static layout will take care of the center alignment of the text in canvas.