Java Android Canvas.drawText(…) equally big in all

2019-06-04 22:15发布

问题:

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?

回答1:

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



回答2:

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.

  1. 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.


回答3:

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.



回答4:

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