android文字描边效果

关于这种效果,网上能找出一堆,主要是两种方法,一种是一个textview里嵌套一个textview,另一种是通过双层绘制的方法.前一种需要两个textview明显不优雅,后一种如果在描边宽度很宽时,会出现显示不全的问题,究其原因就是加描边后宽度测量未将描边算进去, 所以我修正了一下,代码如下:

public class StrokeTextView extends TextView {

    private TextPaint paint;
    private int mInnerColor;
    private int mOuterColor;
    private int mStrokeWidth = 2;
    private int bottomY=0;
    private TextGravity alignStyle = TextGravity.Left;
    private enum TextGravity { Left, Center, Right }

    public StrokeTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs,0);
    }

    public StrokeTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context,attrs,defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        paint = this.getPaint();
        //获取自定义的XML属性名称
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.StrokeTextView);
        //获取对应的属性值
        this.mInnerColor = a.getColor(R.styleable.StrokeTextView_innnerColor,0xffffff);
        this.mOuterColor = a.getColor(R.styleable.StrokeTextView_outerColor,0xffffff);
        this.mStrokeWidth= (int) a.getDimension(R.styleable.StrokeTextView_strokeWidth,6);
        this.alignStyle = TextGravity.values()[a.getInt(R.styleable.StrokeTextView_text_gravity, 0) % TextGravity.values().length];

        paint.setTextAlign(Paint.Align.CENTER);
        Paint.FontMetrics fontMetrics = paint.getFontMetrics();
        bottomY= (int) -fontMetrics.top;
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        String text = getText().toString();
        int width = (int) paint.measureText(text)+getPaddingLeft()+getPaddingRight()+mStrokeWidth*2;
        width = Math.max(width,getMeasuredWidth());
        setMeasuredDimension(width,getMeasuredHeight());
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // 描外层
        setTextColorUseReflection(mOuterColor);
        paint.setStrokeWidth(mStrokeWidth); // 描边宽度
        paint.setStyle(Paint.Style.FILL_AND_STROKE); // 描边种类
        paint.setFakeBoldText(true); // 外层text采用粗体
        drawText(canvas);

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

    private void drawText(Canvas canvas) {
        int dx = mStrokeWidth;
        paint.setTextAlign(Paint.Align.LEFT);
        switch (alignStyle) {
            case Center:
                dx = getWidth() / 2;
                paint.setTextAlign(Paint.Align.CENTER);
                break;
            case Right:
                dx = getWidth() - mStrokeWidth;
                paint.setTextAlign(Paint.Align.RIGHT);
                break;
        }
        canvas.drawText(getText().toString(), dx, bottomY, paint);
    }


    /**
     * 使用反射的方法进行字体颜色的设置
     * @param color
     */
    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();
        }
        paint.setColor(color);
    }



}

attrs.xml配置:

 <declare-styleable name="StrokeTextView">
        <attr name="outerColor" format="color|reference" />
        <attr name="innnerColor" format="color|reference" />
        <attr name="strokeWidth" format="dimension" />
        <attr name="text_gravity">
            <enum name="left" value="0" />
            <enum name="center" value="1" />
            <enum name="right" value="2" />
        </attr>
    </declare-styleable>

其中text_gravity属性控制文字绘制的对齐方式,最后效果完全没有显示不全的现象.
关于文字绘制基准,可见 http://blog.csdn.net/jishoujiang/article/details/51580074

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值