前言:之前有个项目需求,TextView 文本国际化后,显示英文会比较长,自动就换行了,导致不好看;要求是将文字只显示一行,把字体缩小
思路:获取需要显示的文本需要的像素宽度,不断的比较 TextView 有效的显示宽度,大于则 textSize 就不断 -1,直到一行能显示完全
接下来看代码:
public class SingleLineZoomTextView extends TextView {
private Paint mPaint;
private float mTextSize;
public SingleLineZoomTextView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public SingleLineZoomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public SingleLineZoomTextView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
}
/**
* getTextSize 返回值是以像素(px)为单位的,而 setTextSize() 默认是 sp 为单位
* 因此我们要传入像素单位 setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
*/
private void refitText(String text, int textWidth) {
if (textWidth > 0) {
mTextSize = this.getTextSize();//这个返回的单位为px
mPaint = new Paint();
mPaint.set(this.getPaint());
int drawWid = 0;//drawableLeft,Right,Top,Buttom 所有图片的宽
Drawable[] draws = getCompoundDrawables();
for (int i = 0; i < draws.length; i++) {
if(draws[i]!= null){
drawWid += draws[i].getBounds().width();
}
}
//获得当前TextView的有效宽度
int availableWidth = textWidth - this.getPaddingLeft()
- this.getPaddingRight()- getCompoundDrawablePadding()- drawWid;
//所有字符所占像素宽度
float textWidths = getTextLength(mTextSize, text);
while(textWidths > availableWidth){
mPaint.setTextSize(--mTextSize);//这里传入的单位是 px
textWidths = getTextLength(mTextSize, text);
}
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);//这里设置单位为 px
}
}
/**
* @param textSize
* @param text
* @return 字符串所占像素宽度
*/
private float getTextLength(float textSize,String text){
mPaint.setTextSize(textSize);
return mPaint.measureText(text);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
refitText(getText().toString(), this.getWidth());
}
}
直接在 xml 布局中引用就可以了 ;
注:上面用的单位均为 px