Android canvas drawText - how to bottom align text? - android

I have a custom View which is supposed to draw some text bottom aligned.
Size of text should be 50% of view height.
How should I change this code to work correctly?
#Override
protected void onDraw(Canvas canvas)
{
float h = getMeasuredHeight();
float textHeight = h*0.5f;
paint.setTextSize(textHeight);
String str = "Abcdefghijklm";
paint.getTextBounds(str, 0, str.length(), bounds);
float height = bounds.height();
float yPos = height;
canvas.drawText(str, 0, yPos, paint);
}

Replace your yPos to:
float yPos = getHeight() - bounds.getHeight();

Related

Full Text not showing into image

I am trying to convert text into image using below code :
public Bitmap textAsBitmap(String text, float textSize) {
Paint paint = new Paint(ANTI_ALIAS_FLAG);
paint.setTextSize(textSize);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setTextAlign(Paint.Align.CENTER);
float baseline = -paint.ascent(); // ascent() is negative
int width = (int) (paint.measureText(text) + 0.5f); // round
int height = (int) (baseline + paint.descent() + 0.5f);
Bitmap image = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(image);
canvas.drawText(text, 0, baseline, paint);
return image;
}
Its convert text into image but problem is show half text.It should show "favorite subject is english"!
what i am doing wrong ? or how should i solve this problem
Choose your width & height wisely,
Something like I did in my case
public Bitmap textAsBitmap(String text, float textSize) {
Paint paint = new Paint(ANTI_ALIAS_FLAG);
paint.setTextSize(textSize);
paint.setColor(Color.BLACK);
paint.setTextAlign(Paint.Align.LEFT);
float baseline = -paint.ascent(); // ascent() is negative
int width = (int) (paint.measureText(text) + 0.0f); // round
int height = (int) (baseline + paint.descent() + 0.0f);
int actualWidth = width;
if (width > height)
height = width;
else
width = height;
Bitmap image = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(image);
canvas.drawText(text, width / 2 - actualWidth / 2, baseline, paint);
return image;
}
Problem is with paint.setTextAlign(Paint.Align.CENTER);, this property considers center as (0,0). So your text is actually at center according to (0,0).
Just remove paint.setTextAlign(Paint.Align.CENTER); and your code is working!!

DrawArc on image, positioning issue

I have a drawable of a gauge and I try to draw a line on it. (Fixed position, not fixed value)
Unfortunately I don't have any experience with drawing. (And I think its hard to understand)
At the moment it looks like this:
https://i.stack.imgur.com/5tkXEl.png
As you can see, its not positioned right and I'm quite afraid of looking at it on other devices.
Code (Class extends View):
private void init(Context context) {
bounds = new Rect();
gaugeBackground = ContextCompat.getDrawable(context, R.drawable.gauge);
arcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
arcPaint.setColor(Color.RED);
arcPaint.setStyle(Paint.Style.STROKE);
arcPaint.setStrokeWidth(7f);
}
protected void onDraw(Canvas canvas) {
canvas.getClipBounds(bounds);
gaugeBackground.setBounds(bounds);
gaugeBackground.draw(canvas);
float padding = 5;
float size = getWidth() < getHeight() ? getWidth() : getHeight();
float width = size - (2 * padding);
float height = size - (2 * padding);
float radius = (width < height ? width /2 : height /2);
float rectLeft = (width /2) - radius + padding;
float rectTop = (getHeight() /2) - radius + padding;
float rectRight = (getWidth() /2) - radius + padding + width;
float rectBottom = (getHeight() /2) - radius + padding + height;
RectF mRect = new RectF(rectLeft, rectTop, rectRight, rectBottom);
canvas.drawArc(mRect, 119f, 300f, false, arcPaint);
}
Can someone provide helpful information? I hope I finally get the whole RectF/Drawing stuff..
Oh well, I had multiple issues with my implementation.
Main issue: The Background Image was 'warped', so the gauge wasn't really round.
Also: The code was kind of messed up and way too complicated.
I leave the question here - maybe it helps someone in the future.
protected void onDraw(Canvas canvas) {
canvas.getClipBounds(bounds);+
//0.86 == Aspect Ratio of the Background
gaugeBackground.setBounds(0, 0, bounds.right, (int) Math.round(bounds.bottom * 0.86));
gaugeBackground.draw(canvas);
float padding = 3;
float size = getWidth() < getHeight() ? getWidth() : getHeight();
float width = size - (2 * padding);
float height = size - (2 * padding);
RectF mRect = new RectF(padding, padding, width, height);
canvas.drawArc(mRect, 134f, 271f, false, arcPaint);
}

Android: OvalShape Drawable clipped at edges

I'm trying to create a OvalShape Drawable with border. To give it an elevated effect, I'm adding shadows around the border.
Relevant code:
class Badge extends ShapeDrawable{
void Badge(){
borderPaint = new Paint();
borderPaint.setColor(borderColor);
borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(borderThickness);
borderPaint.setAntiAlias(true);
borderPaint.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
}
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
Rect r = getBounds();
// draw border if needed
if (borderThickness > 0) {
drawBorder(canvas);
}
int count = canvas.save();
canvas.translate(r.left, r.top);
// draw text inside badge
int width = this.width < 0 ? r.width() : this.width;
int height = this.height < 0 ? r.height() : this.height;
int fontSize = this.fontSize < 0 ? (Math.min(width, height) / 2) : this.fontSize;
textPaint.setTextSize(fontSize);
Rect textBounds = new Rect();
textPaint.getTextBounds(text, 0, text.length(), textBounds);
canvas.drawText(text, width / 2, height / 2 - textBounds.exactCenterY(), textPaint);
canvas.restoreToCount(count);
}
private void drawBorder(Canvas canvas) {
RectF rect = new RectF(getBounds());
rect.inset(borderThickness / 2, borderThickness / 2);
canvas.drawOval(rect, borderPaint);
}
}
However, the border drawn is clipped at the edges as you can see in the image. Also as the size of the drawable decreases, the edges gets clipped more.
What modification should I do in the code to achieve a perfect circle?

Animation not fluent Android Wear

I'm starting with Android Wear and I want to make a circle animation, making grow.
I know how to do it, I think, but it's doing it very very slow, hope you can help me
I have this class variable
Paint mAnimation;
intialized on the method OnCreate
mAnimation = new Paint(Paint.ANTI_ALIAS_FLAG);
mAnimation.setStyle(Paint.Style.FILL);
mAnimation.setColor(Color.GREEN);
and on the OnDraw method I have
#Override
public void onDraw(Canvas canvas, Rect bounds) {
int width = bounds.width();
int height = bounds.height();
float centerX = width / 2f;
float centerY = height / 2f;
// Draw the background.
canvas.drawRect(0, 0, bounds.width(), bounds.height(), mBackgroundPaint);
canvas.drawCircle(0, centerY, radiusPlus, mAnimation);
radiusPlus += 20;
}
The animation is "correct", but is very slow, like if was paused.
Thanks!!
EDIT
I found a example and now I finally found why. I didn't invalidate the view at the end of the OnDraw. Now It's working fine. Thanks.
#Override
public void onDraw(Canvas canvas, Rect bounds) {
int width = bounds.width();
int height = bounds.height();
float centerX = width / 2f;
float centerY = height / 2f;
// Draw the background.
canvas.drawRect(0, 0, bounds.width(), bounds.height(), mBackgroundPaint);
canvas.drawCircle(0, centerY, radiusPlus, mAnimation);
radiusPlus += 5;
if (isVisible() && !isInAmbientMode()) {
invalidate();
}
}

Android drawBitmap position parameters

I am new to android graphic programming.
I want to put a bitmap in the centre of my canvas. Hence, i use :
public void onDraw(Canvas canvas) {
float canvasx = (float) canvas.getWidth();
float canvasy = (float) canvas.getHeight();
Then i call the bitmap i want to use,
Bitmap myBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.myBitmap);
Then i find the coordinate location for my bitmap by using these,
float bitmapx = (float) myBitmap.getWidth();
float bitmapy = (float) myBitmap.getHeight();
float boardPosX = (canvasx - bitmapx) / 2;
float boardPosY = (canvasy - bitmapy) / 2;
Finally, i draw the bitmap using,
canvas.drawBitmap(myBitmap, boardPosX, boardPosY, null);
But, the bitmap is not in the center of the canvas. It's a little bit below the position which i reckon should be the center of the canvas.
Is it correct to get the canvas height and width inside the onDraw() method ?
Any idea what's wrong ?
Thanks in advance.
*Edit :
Finally, i make it work by changing
public void onDraw(Canvas canvas) {
float canvasx = (float) canvas.getWidth();
float canvasy = (float) canvas.getHeight();
to
public void onDraw(Canvas canvas) {
float canvasx = (float) getWidth();
float canvasy = (float) getHeight();
However, i dont know why the change fixes my problem.
Use this:
float boardPosX = ((canvasx/2) - (bitmapx / 2));
float boardPosY = ((canvasy/2) - (bitmapy / 2));
private int mWidth;
private int mHeight;
private float mAngle;
#Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
mWidth = View.MeasureSpec.getSize(widthMeasureSpec);
mHeight = View.MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(mWidth, mHeight);
}
#Override protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.compass);
// Here's the magic. Whatever way you do it, the logic is:
// space available - bitmap size and divide the result by two.
// There must be an equal amount of pixels on both sides of the image.
// Therefore whatever space is left after displaying the image, half goes to
// left/up and half to right/down. The available space you get by subtracting the
// image's width/height from the screen dimensions. Good luck.
int cx = (mWidth - myBitmap.getWidth()) >> 1; // same as (...) / 2
int cy = (mHeight - myBitmap.getHeight()) >> 1;
if (mAngle > 0) {
canvas.rotate(mAngle, mWidth >> 1, mHeight >> 1);
}
canvas.drawBitmap(myBitmap, cx, cy, null);
}

Categories

Resources