Android Canvas DrawText установить размер шрифта от ширины?

Я хочу нарисовать текст на canvas определенной ширины, используя .drawtext

Например, ширина текста всегда должна быть 400px независимо от того, что текст ввода.

Если вводимый текст длиннее, это уменьшит размер шрифта, а если введенный текст будет короче, соответственно увеличится размер шрифта.

3 ответа

Решение

Вот гораздо более эффективный метод:

/**
 * 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://stackru.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);
}

Затем все, что вам нужно сделать, это setTextSizeForWidth(paint, 400, str); (400 является шириной примера в вопросе).

Для еще большей эффективности вы можете сделать Rect статический член класса, спасающий его от создания экземпляров каждый раз. Однако это может привести к проблемам параллелизма и, возможно, помешать ясности кода.

Попробуй это:

/**
 * 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()

Решение Михаэля Шепера кажется хорошим, но оно не сработало для меня, мне нужно было получить наибольший размер текста, который можно нарисовать на моем виде, но этот подход зависит от первого размера текста, который вы установили. Каждый раз, когда вы устанавливаете другой размер, вы Получите разные результаты, которые не могут сказать, что это правильный ответ в любой ситуации.

Поэтому я попробовал другой способ:

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;
        }
    }
}

Это просто, я увеличиваю размер текста до тех пор, пока размеры прямоугольника не станут достаточно близки к maxWidth а также maxHeight, чтобы уменьшить повторы цикла просто изменить step к большему значению (точность против скорости), Может быть, это не лучший способ достичь этого, но это работает.

Другие вопросы по тегам