TextView添加描边——视频字幕

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.widget.TextView;

import java.lang.reflect.Field;

public class WrapTextView extends TextView {

    private int mBorderColor = Color.GRAY;
    private int mInnerColor = Color.WHITE;
    private boolean mBorderText = true;
    private TextPaint mTextPaint;

    public WrapTextView(Context context) {
        this(context, null);
    }

    public WrapTextView(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.textViewStyle);
    }

    public WrapTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mTextPaint = this.getPaint();
        mInnerColor = getCurrentTextColor();
    }

    /**
     * onDraw  draw border first
     */
    @Override
    protected void onDraw(Canvas canvas) {
        if (mBorderText) {
            // 描外层
            setTextColorUseReflection(mBorderColor);
            int width = 1;
            mTextPaint.setStrokeWidth(width); // 描边宽度
            mTextPaint.setStyle(Paint.Style.STROKE); // 画笔空心
            mTextPaint.setFakeBoldText(true); // 外层text采用粗体
            super.onDraw(canvas);

            // 描内层,恢复原先的画笔
            setTextColorUseReflection(mInnerColor);
            mTextPaint.setStrokeWidth(0);
            mTextPaint.setStyle(Paint.Style.FILL);
            mTextPaint.setFakeBoldText(false);
        }
        super.onDraw(canvas);
    }

    /**
     * 使用反射的方法进行字体颜色的设置
     * 其实就是 this.setTextColor(); 但是这个系统方法里会调用invalidate(); 最终的效果导致这段代码无限循环
     * 反射部分:
     * 1. Class.getDeclaredField(String name); 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段(包括私有成员)
     * 2. 获取私有属性的时候必须先设置Accessible为true,然后才能获取
     * 3. 通过Field.get(Object obj)获取属性的值,通过Field.set(Object obj,value)重新设置新的属性值
     */
    private void setTextColorUseReflection(int color) {
        Field textColorField;
        try {
            textColorField = TextView.class.getDeclaredField("mCurTextColor");
            textColorField.setAccessible(true);
            textColorField.set(this, color);
            textColorField.setAccessible(false);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        mTextPaint.setColor(color);
    }
}

转载于:https://www.cnblogs.com/cheneasternsun/p/5402632.html

猜你喜欢

转载自blog.csdn.net/nnmmbb/article/details/82417391
今日推荐