How to adjust text font size to fit textview

后端 未结 22 2259
無奈伤痛
無奈伤痛 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:50

    This is speedplane's FontFitTextView, but it only decreases font size if needed to make the text fit, and keeps its font size otherwise. It does not increase the font size to fit height.

    public class FontFitTextView extends TextView {
    
        // Attributes
        private Paint mTestPaint;
        private float defaultTextSize;
    
        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());
            defaultTextSize = getTextSize();
        }
    
        /* 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) {
    
            if (textWidth <= 0 || text.isEmpty())
                return;
    
            int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight();
    
            // this is most likely a non-relevant call
            if( targetWidth<=2 )
                return;
    
            // text already fits with the xml-defined font size?
            mTestPaint.set(this.getPaint());
            mTestPaint.setTextSize(defaultTextSize);
            if(mTestPaint.measureText(text) <= targetWidth) {
                this.setTextSize(TypedValue.COMPLEX_UNIT_PX, defaultTextSize);
                return;
            }
    
            // adjust text size using binary search for efficiency
            float hi = defaultTextSize;
            float lo = 2;
            final float threshold = 0.5f; // How close we have to be
            while (hi - lo > threshold) {
                float size = (hi + lo) / 2;
                mTestPaint.setTextSize(size);
                if(mTestPaint.measureText(text) >= targetWidth ) 
                    hi = size; // too big
                else 
                    lo = size; // too small
    
            }
    
            // Use lo so that we undershoot rather than overshoot
            this.setTextSize(TypedValue.COMPLEX_UNIT_PX, lo);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
            int height = getMeasuredHeight();
            refitText(this.getText().toString(), parentWidth);
            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());
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            if (w != oldw || h != oldh) {
                refitText(this.getText().toString(), w);
            }
        }
    
    }
    

    Here is an example how it could be used in xml:

    
    

    This would keep the font size to 60sp as long as the text fits in width. If the text is longer, it will decrease font size. In this case, the TextViews height will also change because of height=wrap_content.

    If you find any bugs, feel free to edit.

提交回复
热议问题