简体   繁体   English

android canvas drawText从宽度设置字体大小?

[英]android canvas drawText set font size from width?

I want to draw text on canvas of certain width using .drawtext 我想使用.drawtext在一定宽度的canvas上绘制文本

For example, the width of the text should always be 400px no matter what the input text is. 例如,无论输入文本是什么,文本的宽度应始终为400px

If input text is longer it will decrease the font size, if input text is shorter it will increase the font size accordingly. 如果输入文本较长则会减小字体大小,如果输入文本较短,则会相应地增加字体大小。

Here's a much more efficient method: 这是一种更有效的方法:

/**
 * Sets the text size for a Paint object so a given string of text will be a
 * given width.
 * 
 * @param paint
 *            the Paint to set the text size for
 * @param desiredWidth
 *            the desired width
 * @param text
 *            the text that should be that width
 */
private static void setTextSizeForWidth(Paint paint, float desiredWidth,
        String text) {

    // Pick a reasonably large value for the test. Larger values produce
    // more accurate results, but may cause problems with hardware
    // acceleration. But there are workarounds for that, too; refer to
    // http://stackoverflow.com/questions/6253528/font-size-too-large-to-fit-in-cache
    final float testTextSize = 48f;

    // Get the bounds of the text, using our testTextSize.
    paint.setTextSize(testTextSize);
    Rect bounds = new Rect();
    paint.getTextBounds(text, 0, text.length(), bounds);

    // Calculate the desired size as a proportion of our testTextSize.
    float desiredTextSize = testTextSize * desiredWidth / bounds.width();

    // Set the paint for that size.
    paint.setTextSize(desiredTextSize);
}

Then, all you need to do is setTextSizeForWidth(paint, 400, str); 然后,你需要做的就是setTextSizeForWidth(paint, 400, str); (400 being the example width in the question). (400是问题中的示例宽度)。

For even greater efficiency, you can make the Rect a static class member, saving it from being instantiated each time. 为了获得更高的效率,您可以将Rect为静态类成员,从而使其不会每次都被实例化。 However, this may introduce concurrency issues, and would arguably hinder code clarity. 但是,这可能会引入并发问题,并且可能会阻碍代码清晰度。

Try this: 试试这个:

/**
 * Retrieve the maximum text size to fit in a given width.
 * @param str (String): Text to check for size.
 * @param maxWidth (float): Maximum allowed width.
 * @return (int): The desired text size.
 */
private int determineMaxTextSize(String str, float maxWidth)
{
    int size = 0;       
    Paint paint = new Paint();

    do {
        paint.setTextSize(++ size);
    } while(paint.measureText(str) < maxWidth);

    return size;
} //End getMaxTextSize()

Michael Scheper's solution seems nice but it didn't work for me, I needed to get the largest text size that is possible to draw in my view but this approach depends on the first text size you set, Every time you set a different size you'll get different results that can not say it is the right answer in every situation. Michael Scheper的解决方案似乎不错,但它对我不起作用,我需要获得可以在我的视图中绘制的最大文本大小,但这种方法取决于您设置的第一个文本大小,每次设置不同的大小时会得到不同的结果,不能说它在每种情况下都是正确的答案。

So I tried another way: 所以我尝试了另一种方式:

private float calculateMaxTextSize(String text, Paint paint, int maxWidth, int maxHeight) {
    if (text == null || paint == null) return 0;
    Rect bound = new Rect();
    float size = 1.0f;
    float step= 1.0f;    
    while (true) {
        paint.getTextBounds(text, 0, text.length(), bound);
        if (bound.width() < maxWidth && bound.height() < maxHeight) {
            size += step;
            paint.setTextSize(size);
        } else {
            return size - step;
        }
    }
}

It's simple, I increase the text size until the text rect bound dimensions are close enough to maxWidth and maxHeight , to decrease the loop repeats just change step to a bigger value ( accuracy vs speed ), Maybe it's not the best way to achieve this but It works. 这很简单,我增加文本大小,直到文本矩形边界尺寸足够接近maxWidthmaxHeight ,减少循环重复只是将step更改为更大的值( 精度与速度 ),也许这不是实现此目的的最佳方法有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM