赞
踩
一图胜千言
文字镂空效果主要有两种实现方式:
1,自动义View,在canvas中绘制圆角矩形作为背景,然后绘制文字,通过PorterDuff.Mode.DST_OUT把背景擦除,实现镂空效果。如上图中的第一个。
2,自定义TextView,定义两Bitmap,分别在Bitmap上画背景和文字前景,然后通过PorterDuff.Mode.DST_OUT,把背景擦除,实现镂空效果。如上图中的第二个。
比较:两种方式原理上是一样的,但是第二种方式继承自TextView,可以直接使用TextView的属性,如字体大小、颜色、样式等等。而第一种则需要定义大量的属性。
下面分别介绍两种方式。
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"
- />
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="撒拉嘿!"/>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。