字体自适应宽度的TextView

来源:互联网 发布:淘宝卖家开通花呗付款 编辑:程序博客网 时间:2024/04/30 00:25
  • 项目遇到 TextView宽度有限时,但是需要显示的文字长度不确定,如:recycleview子布局中显示地址。
  • ios 原生有自适应textview,android没找到。
  • 下面是从网上找的自适应textview,用起来能满足要求,字体会随着长度改变去适应textview的宽度。
  • 用法跟原生textview一样,只是xml把textview 换为FontFitTextView
<your_package.FontFitTextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="字体会随着长度改变去适应textview的宽度"/>
  • FontFitTextView .java
package your_package;import android.content.Context;import android.graphics.Paint;import android.util.AttributeSet;import android.util.TypedValue;/** * Created by lwj on 2017/9/29. */public class FontFitTextView extends android.support.v7.widget.AppCompatTextView {    // 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);        }    }}
原创粉丝点击