最近項目里面RecyclerView做4列顯示文字標(biāo)簽,但是按UI給的標(biāo)注設(shè)置后况毅,標(biāo)簽還是可能不止占一行晓殊,一些小屏手機(jī)時就不是預(yù)期效果了碗短,于是自己摸索了一個view來根據(jù)寬高調(diào)節(jié)textSize:
image.png
代碼貼出來,可能還不是很完善悦陋,一個思路:
/**
* use to do 如果限定textView的寬度蜈彼,則根據(jù)寬度顯示文字,字體大小改變
* 繪制只在居中繪制的樣式,其他樣式需要自己完善
*
* @author zhangdong on 2018/2/11 0011.
* @version 1.0
* @see .
* @since 1.0
*/
public class WrapContentTextView extends AppCompatTextView {
private static final String TAG = "WrapContentTextView";
private Paint mPaint;
private Boolean isWrapContent = false;//是否開啟根據(jù)view的寬高調(diào)節(jié)字體大小
public void setWrapContent(Boolean wrapContent) {
isWrapContent = wrapContent;
invalidate();
}
public Boolean getWrapContent() {
return isWrapContent;
}
public WrapContentTextView(Context context) {
super(context);
init();
}
public WrapContentTextView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.getTheme()
.obtainStyledAttributes(attrs, R.styleable.WrapContentTextView, 0, 0);
isWrapContent = typedArray.getBoolean(R.styleable.WrapContentTextView_isWrapContent, false);
typedArray.recycle();
init();
}
public WrapContentTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
float density = getResources().getDisplayMetrics().density;
Log.d(TAG, "onDraw: ------- 屏幕密度系數(shù)density = " + density);
}
@Override
protected void onDraw(Canvas canvas) {
if (isWrapContent) {
int width = getWidth();
int height = getHeight();
Log.d(TAG, "onDraw: ------- View的width = " + width + "; View的height = " + height);
CharSequence text = getText();
if (!TextUtils.isEmpty(text)) {
//文字的字?jǐn)?shù)
int length = text.length();
//view的內(nèi)邊距
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
int paddingTop = getPaddingTop();
int paddingBottom = getPaddingBottom();
Log.d(TAG, "onDraw: ------- paddingLeft = " + paddingLeft +
"; paddingTop = " + paddingTop +
"; paddingRight = " + paddingRight +
"; paddingBottom = " + paddingBottom);
//文字可繪制的寬高
int textWidth = width - paddingLeft - paddingRight;
int textHeight = height - paddingTop - paddingBottom;
//一個字可繪制的寬度
int oneWidth = textWidth / length;
//一個字可繪制的寬度與可繪制的高度取最小的值
int textSize = Math.min(oneWidth, textHeight);
Log.d(TAG, "onDraw: ------- 文字長度:" + length +
"; 可繪制的textWidth = " + textWidth +
"; oneWidth = " + oneWidth +
"; 可繪制的textHeight = " + textHeight);
//當(dāng)前文字的size
float size = getTextSize();
float measureText = getPaint().measureText(text, 0, length);
Log.d(TAG, "onDraw: ------- 初始文字的size = " + size +
"; 初始文字的寬measureText = " + measureText);
//獲取當(dāng)前文字的高度
Paint.FontMetrics fontMetrics = getPaint().getFontMetrics();
float tHeight = fontMetrics.bottom - fontMetrics.top;
Log.d(TAG, "onDraw: ------- 初始文字的fontMetrics.bottom= " + fontMetrics.bottom +
"; 初始文字的fontMetrics.top= " + fontMetrics.top +
"; 初始文字的高度tHeight= " + tHeight);
float newSize = 0;
//新的文字大小根據(jù)寬度比例關(guān)系得到
float newSizeW = size * textSize * length / measureText;
//新的文字大小根據(jù)高度比例關(guān)系得到
float newSizeH = size * textHeight / tHeight;
Log.d(TAG, "onDraw: ------- 根據(jù)寬度比例關(guān)系得到newSizeW= " + newSizeW +
"; 根據(jù)高度比例關(guān)系得到newSizeH= " + newSizeH);
newSize = Math.min(newSizeW, newSizeH);
Log.d(TAG, "onDraw: ------- 取最小的文字大小設(shè)置給畫筆newSize : " + newSize);
mPaint.setTextSize(newSize);
mPaint.setColor(getCurrentTextColor());
Rect textRect = new Rect();
mPaint.getTextBounds(text.toString(), 0, length, textRect);
Paint.FontMetrics mPaintFontMetrics = mPaint.getFontMetrics();
float top = mPaintFontMetrics.top;
float bottom = mPaintFontMetrics.bottom;
//文字繪制的x軸起點
int startX = (width - textRect.width() + paddingLeft - paddingRight) / 2;
//文字繪制的中心
int textCenterY = textHeight + paddingTop - textHeight / 2;
//文字繪制的基線 BaseLine
int startY = (int) (textCenterY - (bottom - top) / 2 - top);
Log.d(TAG, "onDraw: ------- textRect.width()= " + textRect.width() +
"; textRect.height()= " + textRect.height());
Log.d(TAG, "onDraw: ------- 繪制的起點:X = " + startX + "; Y = " + startY);
canvas.drawText(text, 0, length, startX, startY, mPaint);
}
} else super.onDraw(canvas);
}
}
需要的自定義屬性:是否需要view根據(jù)寬高改變textSize
<declare-styleable name="WrapContentTextView">
<attr name="isWrapContent" format="boolean" />
</declare-styleable>
使用:
<com.example.zd.mycontentprovider.view.WrapContentTextView
android:id="@+id/tv_test"
android:layout_width="160dp"
android:layout_height="60dp"
android:layout_marginTop="100dp"
android:background="#70000000"
android:textColor="#ff0000"
app:isWrapContent="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="this is test text" />
這一句代碼是控制的:
app:isWrapContent="true"
當(dāng)然也可以在代碼里面動態(tài)設(shè)置俺驶,調(diào)用方法:
public void setWrapContent(Boolean wrapContent) {
isWrapContent = wrapContent;
invalidate();
}
eg:
wrapContentTextView.setText("好的的一個家幸逆,哎呀我大中華");
wrapContentTextView.setWrapContent(true);
運(yùn)行效果還不錯:
image.png