根据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>
###本文为小菜鸟学习记录,如有错误请大家批评指正