根据textView的宽度自动伸缩字体的size

根据textView的宽度自动伸缩字体的size

开发过程中经常需要根据需求来自定义控件,今天就分享一个可自动伸缩字体大小的textView。

需求如下

  • 根据textView的真实宽度来自适应字体的大小
  • 可设置最小字体size,如当text文本缩小至设置的最小size,仍不能在控件中显示完全,则尾部以省略号结尾
    ###代码如下
public class FitTextView extends android.support.v7.widget.AppCompatTextView {
    //此处最小size设置为18,可随意修改
    private int mMinTextSize = 18;

    private Paint mTextPaint;
    private float mTextSize;
    private int textColor;
    private float ellipsisWidth;

     public FitTextView(Context context) {
        this(context, null);
    }

    public FitTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FitTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray typedArray = context.obtainStyledAttributes(attrs,
                R.styleable.FitTextView);
        textColor = typedArray.getColor(R.styleable.FitTextView_android_textColor, Color.BLACK);
        mTextPaint = this.getPaint();
        mTextPaint.setColor(textColor);

    }

    private void refitText(String text, int textViewWidth) {
        if (text == null || text.equals("") || textViewWidth < 0) {
            return;
        }

        //此处赋值为this.getPaint(),而不是 new Paint();是因为后者会因中文,英文,符号,不同测量会有偏差
        mTextPaint = this.getPaint();
        int availableTextViewWidth = getWidth() - getPaddingLeft() - getPaddingRight();
        float[] charWidthArr = new float[text.length()];
        Rect boundsRect = new Rect();
        mTextPaint.getTextBounds(text, 0, text.length(), boundsRect);
        int textWidth = boundsRect.width();
        int textNum = 0;
        mTextSize = getTextSize();

        while (textWidth > availableTextViewWidth) {
            if (mTextSize > mMinTextSize) {
                mTextSize -= 1;
                mTextPaint.setTextSize(mTextSize);
                textNum = mTextPaint.getTextWidths(text, charWidthArr);
                textWidth = 0;
                for (int i = 0; i < textNum; i++) {
                    textWidth += charWidthArr[i];
                }
            }else {
                //若size已经是限定mMinTextSize,则显示为尾部省略
                ellipsisWidth = 0;
                for (int i = 0; i < textNum; i++) {
                    if (ellipsisWidth <= availableTextViewWidth - 25){
                        ellipsisWidth += charWidthArr[i];
                    }else {
                        String text1 = text.substring(0,i) + "...";
                        setText(text1);
                        break;
                    }
                }
                break;
            }
        }
        this.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        refitText(this.getText().toString(), this.getWidth());
        //super.onDraw(canvas);
        //mTextPaint.setColor(Color.BLUE);
         Paint.FontMetricsInt fm = mTextPaint.getFontMetricsInt();
        //一定要自己绘制text文本,如直接使用父类方法 super.onDraw(canvas);字体会正常收缩,但只会显示缩小之前在textView中显示的文本,将文本绘制到中心位置
        canvas.drawText(this.getText().toString(), 0, getHeight() / 2  +(fm.bottom - fm.top)/2 - fm.bottom, mTextPaint);

    }
###在布局文件中,textView的宽度可随意设置,如
    <FitTextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"/>
  
    <FitTextView
      android:layout_width="120dp"
      android:layout_height="wrap_content"/>
 
    <FitTextView
      android:layout_width="0dp"
      android:layout_weight="1"
      //设置单行很重要
      android:maxLines="1"
      android:layout_height="wrap_content"/>

<!-- FitTextView -->
    <declare-styleable name="FitTextView">
        <attr name="android:textColor"/>
    </declare-styleable>

###本文为小菜鸟学习记录,如有错误请大家批评指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值