I have drawn text with canvas.drawText(...)
in my project and tested it against with different devices.
However, the size of the text varies a lot from screen to screen.
I have tried to multiply it with getResources().getDisplayMetrics().density
but they are still slightly not the same size.
Is there a way to get the text to have the same size on different devices?
hi you can look at this post , http://catchthecows.com/?p=72, i think it helps to you.
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// save view size
mViewWidth = w;
mViewHeight = h;
// first determine font point size
adjustTextSize();
// then determine width scaling
// this is done in two steps in case the
// point size change affects the width boundary
adjustTextScale();
}
void adjustTextSize() {
mTextPaint.setTextSize(100);
mTextPaint.setTextScaleX(1.0f);
Rect bounds = new Rect();
// ask the paint for the bounding rect if it were to draw this
// text
mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
// get the height that would have been produced
int h = bounds.bottom - bounds.top;
// make the text text up 70% of the height
float target = (float)mViewHeight*.7f;
// figure out what textSize setting would create that height
// of text
float size = ((target/h)*100f);
// and set it into the paint
mTextPaint.setTextSize(size);
}
void adjustTextScale() {
// do calculation with scale of 1.0 (no scale)
mTextPaint.setTextScaleX(1.0f);
Rect bounds = new Rect();
// ask the paint for the bounding rect if it were to draw this
// text.
mTextPaint.getTextBounds(mText, 0, mText.length(), bounds);
// determine the width
int w = bounds.right - bounds.left;
// calculate the baseline to use so that the
// entire text is visible including the descenders
int text_h = bounds.bottom-bounds.top;
mTextBaseline=bounds.bottom+((mViewHeight-text_h)/2);
// determine how much to scale the width to fit the view
float xscale = ((float) (mViewWidth-getPaddingLeft()-getPaddingRight())) / w;
// set the scale for the text paint
mTextPaint.setTextScaleX(xscale);
}
@Override
protected void onDraw(Canvas canvas) {
// let the ImageButton paint background as normal
super.onDraw(canvas);
// draw the text
// position is centered on width
// and the baseline is calculated to be positioned from the
// view bottom
canvas.drawText(mText, mViewWidth/2, mViewHeight-mTextBaseline, mTextPaint);
}
https://github.com/catchthecows/BigTextButton
What this
getResources().getDisplayMetrics().density
does is that it makes it look similar on same screen sizes with different densities. Appreciate your move.
There are two solution to your problem.
1. Try having Large, xlarge and normal layouts. Adjust them accordingly on the respective layouts to look even.
- Get screen percentage occupancy (height/width and Right/left/top/bottom of canvas in percentage to adjust them evenly on different screens) of the canvas. And apply it as layoutParams.
The Paint class takes a text size in pixels. If you're going to draw text directly through it, then you need to handle unit conversions before calling paint.setTextSize(float size). Always use sp or dp units and you may want to include at least separate dimens.xml resources for small, normal, large, and xlarge screens.
When calling Canvas.drawText()
the text size is first determined by the passed in Paint
object, which can be set via Paint.setTextSize()
. The text size is automatically scaled by Canvas
based on the canvas density, which can be found using Canvas.getDensity()
.
When setting the text size on a paint object that will be drawn on Canvas, work with a unit value of dp
or sp
and let Canvas handle the scaling for you.
And of course you may need to specify different values depending on the screen size: Supporting Multiple Screens