How to adjust text font size to fit textview

后端 未结 22 1778
無奈伤痛
無奈伤痛 2020-11-22 05:15

Is there any way in android to adjust the textsize in a textview to fit the space it occupies?

E.g. I\'m using a TableLayout and adding several Te

22条回答
  •  遥遥无期
    2020-11-22 05:44

    I've been working on improving the excellent solution from speedplane, and came up with this. It manages the height, including setting the margin such that the text should be centered correctly vertically.

    This uses the same function to get the width, as it seems to work the best, but it uses a different function to get the height, as the height isn't provided anywhere. There are some corrections that need to be made, but I figured out a way to do that, while looking pleasing to the eye.

    import android.content.Context;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.util.AttributeSet;
    import android.util.TypedValue;
    import android.widget.TextView;
    
    public class FontFitTextView extends TextView {
    
        public FontFitTextView(Context context) {
            super(context);
            initialize();
        }
    
        public FontFitTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
            initialize();
        }
    
        private void initialize() {
            mTestPaint = new Paint();
            mTestPaint.set(this.getPaint());
    
            //max size defaults to the initially specified text size unless it is too small
        }
    
        /* Re size the font so the specified text fits in the text box
         * assuming the text box is the specified width.
         */
        private void refitText(String text, int textWidth,int textHeight) 
        { 
            if (textWidth <= 0)
                return;
            int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight();
            int targetHeight = textHeight - this.getPaddingTop() - this.getPaddingBottom();
            float hi = Math.min(targetHeight,100);
            float lo = 2;
            final float threshold = 0.5f; // How close we have to be
    
            Rect bounds = new Rect();
    
            mTestPaint.set(this.getPaint());
    
            while((hi - lo) > threshold) {
                float size = (hi+lo)/2;
                mTestPaint.setTextSize(size);
                mTestPaint.getTextBounds(text, 0, text.length(), bounds);
                if((mTestPaint.measureText(text)) >= targetWidth || (1+(2*(size+(float)bounds.top)-bounds.bottom)) >=targetHeight) 
                    hi = size; // too big
                else
                    lo = size; // too small
            }
            // Use lo so that we undershoot rather than overshoot
            this.setTextSize(TypedValue.COMPLEX_UNIT_PX,(float) lo);
    
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
        {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
            int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
            int height = getMeasuredHeight();
            refitText(this.getText().toString(), parentWidth,height);
            this.setMeasuredDimension(parentWidth, height);
        }
    
        @Override
        protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
            refitText(text.toString(), this.getWidth(),this.getHeight());
        }
    
        @Override
        protected void onSizeChanged (int w, int h, int oldw, int oldh) {
    
            if (w != oldw) {
                refitText(this.getText().toString(), w,h);
            }
        }
    
        //Attributes
        private Paint mTestPaint;
    }
    

提交回复
热议问题