美文网首页
Android TextView 字体描边(修复动态设置无效问题

Android TextView 字体描边(修复动态设置无效问题

作者: 晖仔Milo | 来源:发表于2020-11-05 17:04 被阅读0次

如题,最近业务需求字体增加描边。兴高采烈的从网上copy下来demo运行之后发现在TextView完成onMeasure之后setText出来显示的问题就不带描边效果了,是代码出现问题了嘛?还是我copy错了?

分析了一波源码发现,网上常见的demo都只考虑了界面初始化阶段。也就是你如果在xml文件中或者在TextView绘制成功之前设置了文本,则渲染正常,但一旦如果文案发生变化,想再去更改时,发现描边效果不见了。

怎么解决?
思路:只要文字变化的时候,重新执行onMeasure里的逻辑不就好了?

行动:
然后我简单扒了下TextView的源码,发现每次setText之后都会触发

    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
        if (mTextHelper != null && !PLATFORM_SUPPORTS_AUTOSIZE && mTextHelper.isAutoSizeEnabled()) {
            mTextHelper.autoSizeText();
        }
    }

解决:
不卖关子了,晒源码吧


/**
 * Title:带描边的TextView
 * Describe:
 * Remark:与网上常见的不同,我重写了 {@link #onTextChanged(CharSequence, int, int, int)},这样就支持动态修改了
 * <p>
 * Created by milo
 * E-Mail : 303767416@qq.com
 * 2020/7/16
 */
public class StrokeTextView extends AppCompatTextView {
    private static final String TAG = "StrokeTextView";

    private TextView borderText = null;///用于描边的TextView

    private int mStrokeWidth = 3;
    private int mStrokeColor = R.color.module_magic_border_text;

    public StrokeTextView(Context context) {
        super(context);
        borderText = new TextView(context);
        init();
    }

    public StrokeTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        borderText = new TextView(context, attrs);
        init();
    }

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

    @Override
    public void setLayoutParams(ViewGroup.LayoutParams params) {
        super.setLayoutParams(params);
        borderText.setLayoutParams(params);
    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        super.onTextChanged(text, start, lengthBefore, lengthAfter);

        if (borderText != null) {
            FZLogger.d(TAG, "onTextChanged .. borderText == " + borderText.getText().toString() + ", text == " + text.toString());
            CharSequence borderChar = borderText.getText();
            //两个TextView上的文字必须一致
            if (borderChar == null || !borderChar.equals(this.getText())) {
                borderText.setText(getText());
                this.postInvalidate();
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        CharSequence borderChar = borderText.getText();

        //两个TextView上的文字必须一致
        if (borderChar == null || !borderChar.equals(this.getText())) {
            borderText.setText(getText());
            this.postInvalidate();
        }

        borderText.measure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        borderText.layout(left, top, right, bottom);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        borderText.draw(canvas);
        super.onDraw(canvas);
    }

    public void init() {
        TextPaint tp1 = borderText.getPaint();
        tp1.setStrokeWidth(mStrokeWidth);                                //设置描边宽度
        tp1.setStyle(Paint.Style.STROKE);                                //对文字只描边
        borderText.setTextColor(getResources().getColor(mStrokeColor));  //设置描边颜色
        borderText.setGravity(getGravity());
    }

    private void setStrokeWidth(int strokeWidth) {
        this.mStrokeWidth = strokeWidth;
        init();
        invalidate();
    }

    private void setStrokeColor(@ColorRes int strokeColor) {
        this.mStrokeColor = strokeColor;
        init();
        invalidate();
    }

}

再到代码中尝试一下,是不是任意时刻调用 setText 都可以正确显示描边了呢。

相关文章

网友评论

      本文标题:Android TextView 字体描边(修复动态设置无效问题

      本文链接:https://www.haomeiwen.com/subject/jhlavktx.html