Android TextView文字鏤空效果的兩種實現
阿新 • • 發佈:2018-12-04
一圖勝千言
文字鏤空效果主要有兩種實現方式:
1,自動義View,在canvas中繪製圓角矩形作為背景,然後繪製文字,通過PorterDuff.Mode.DST_OUT把背景擦除,實現鏤空效果。如上圖中的第一個。
2,自定義TextView,定義兩Bitmap,分別在Bitmap上畫背景和文字前景,然後通過PorterDuff.Mode.DST_OUT,把背景擦除,實現鏤空效果。如上圖中的第二個。
比較:兩種方式原理上是一樣的,但是第二種方式繼承自TextView,可以直接使用TextView的屬性,如字型大小、顏色、樣式等等。而第一種則需要定義大量的屬性。
下面分別介紹兩種方式。
一,自動義View方式。
1,初始化
public void init(Context context, AttributeSet attrs) { if (attrs != null) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HollowView); // 獲取要實現的內容 textString = a.getString(R.styleable.HollowView_textString); // 獲取背景色 mBgColor = a.getColor(R.styleable.HollowView_bgColor, mBgColor); if (a.hasValue(R.styleable.HollowView_textSize)) { // 獲取文字大小 textSize = a.getDimension(R.styleable.HollowView_textSize, textSize); } // 獲取圓角半徑 mRadius=a.getDimension(R.styleable.HollowView_radius,mRadius); a.recycle(); } mPaint = new Paint(); mPaint.setTextSize(textSize); mPaint.setAntiAlias(true); mPaint.setColor(mBgColor); Paint.FontMetrics fontMetrics = mPaint.getFontMetrics(); // 計算繪製文字起始點的Y值 drawY = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom; }
2,測量
這裡用了預設的wrap_content測量方式,如果有需要可自行修改。
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 獲取文字寬度 width = FontUtil.getTextWidth(textString, mPaint); // 獲取文字高度 height = FontUtil.getTextHeight(textString, mPaint); // 計算空間應占的寬度 mWidth = width + getPaddingLeft() + getPaddingRight(); // 計算空間應占的高度 mHeight = height + getPaddingTop() + getPaddingBottom(); // 背景的繪製範圍 rectF = new RectF(-mWidth / 2, -mHeight / 2, mWidth / 2, mHeight / 2); setMeasuredDimension(mWidth, mHeight); }
3,繪製
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 移動原點到view中心
canvas.translate(mWidth / 2, mHeight / 2);
// 儲存layer
int layer = canvas.saveLayer(rectF, mPaint);
// 繪製圓角矩形的背景
canvas.drawRoundRect(rectF, mRadius, mRadius, mPaint);
// 設定畫筆PorterDuff.Mode.DST_OUT模式
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
// 繪製文字
canvas.drawText(textString, -width / 2, drawY, mPaint);
mPaint.setXfermode(null);
// 還原圖層
canvas.restoreToCount(layer);
}
這樣就實現了圖中第一個效果。
4,使用
<per.wangsj.myview.view.textview.HollowView
android:id="@+id/hollowView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:textString="撒拉嘿!"
app:bgColor="@color/color_1"
app:textSize="24sp"
app:radius="4dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingTop="4dp"
android:paddingBottom="4dp"
/>
二,自動義TextView方式。
1,初始化屬性,畫筆等
private void init(AttributeSet attrs) {
TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.HollowView);
// 獲取背景顏色屬性
bgColor = typedArray.getColor(R.styleable.HollowView_bgColor, bgColor);
// 獲取圓角半徑屬性
mRadius = typedArray.getDimension(R.styleable.HollowView_radius, mRadius);
// 獲取文字
textString = getText().toString();
// 初始化畫筆
bgPaint = new Paint();
bgPaint.setColor(bgColor);
bgPaint.setAntiAlias(true);
}
2,初始化兩個Bitmap和canvas
通過canvas分別在bitmap上繪製文字,和背景。
private void initCanvas() {
// 顯示文字的Bitmap
textBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_4444);
textCanvas = new Canvas(textBitmap);
// 計算文字開始繪製位置的Y值
Paint.FontMetrics fontMetrics = getPaint().getFontMetrics();
float y = mHeight / 2 + (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
// 在textBitmap上畫背景
textCanvas.drawText(textString, getPaddingLeft(), y, getPaint());
// 繪製背景的bitmap
bgBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_4444);
Canvas bgCanvas = new Canvas(bgBitmap);
// 在bgBitmap上畫背景
bgCanvas.drawRoundRect(0, 0, mWidth, mHeight, mRadius, mRadius, bgPaint);
}
3,繪製
protected void onDraw(Canvas canvas) {
// 儲存圖層
int layer = canvas.saveLayer(0, 0, mWidth, mHeight, bgPaint);
// 畫背景
canvas.drawBitmap(bgBitmap, 0, 0, bgPaint);
// 設定畫筆模式
bgPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
// 畫文字
canvas.drawBitmap(textBitmap, 0, 0, bgPaint);
bgPaint.setXfermode(null);
// 還原圖層
canvas.restoreToCount(layer);
}
程式碼註釋已經比較清楚了,就不多做解釋了。
可以看出,這種方式只需要新增背景色和圓角半徑兩個自定義屬性。
4,使用
<per.wangsj.myview.view.textview.HollowTextView
android:id="@+id/hollowTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
app:bgColor="@color/color_1"
app:radius="4dp"
android:text="撒拉嘿!"/>