android canvas drawText set font size from width?

前端 未结 3 1578
北恋
北恋 2020-12-12 13:36

I want to draw text on canvas of certain width using .drawtext

For example, the width of the text should always be 400px no ma

相关标签:
3条回答
  • 2020-12-12 14:02

    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); (400 being the example width in the question).

    For even greater efficiency, you can make the Rect a static class member, saving it from being instantiated each time. However, this may introduce concurrency issues, and would arguably hinder code clarity.

    0 讨论(0)
  • 2020-12-12 14:04

    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.

    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.

    0 讨论(0)
  • 2020-12-12 14:08

    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()
    
    0 讨论(0)
提交回复
热议问题