Android 神器之SpanableString实现textview部分字体点击事件(不同颜色),并且支持多个点击事件

1.老规矩,咱们先上效果图
Android 神器之SpanableString实现textview部分字体点击事件(不同颜色),并且支持多个点击事件_第1张图片

2.如上图 标红的地方,我们一眼看上去 就是一个TextView上面展示出来的(没错就是一个TextView展示出来的),并且 部分字体颜色不一样,而且这个三个协议是可以点击的,点击跳转到不同页面,怎么实现尼 ?,这里就涉及到一个知识点SpannableString:

    @BindView(R.id.tvIssue)
    TextView tvIssue;
    private int highlightTextNormalColor;
    private int highlightTextPressedColor;
    private int highlightBgNormalColor;
    private int highlightBgPressedColor;
    
   private void initView() {
        highlightTextNormalColor = ContextCompat.getColor(this, R.color.register_text);
        highlightTextPressedColor = ContextCompat.getColor(this, R.color.register_text);
        highlightBgNormalColor = QMUIResHelper.getAttrColor(this, R.attr.actionBarDivider);
        highlightBgPressedColor = QMUIResHelper.getAttrColor(this, R.attr.actionBarDivider);
        tvIssue.setMovementMethod(LinkMovementMethod.getInstance());
        tvIssue.setText(generateSp("注册即表示同意用户注册协议、商户服务协议和隐私权政策"));
    }

    private SpannableString generateSp(String text) {
        String highlight1 = "用户注册协议";
        String highlight2 = "商户服务协议";
        String highlight3 = "隐私权政策";
        SpannableString sp = new SpannableString(text);
        int start = 0, end;
        int index;
        while ((index = text.indexOf(highlight1, start)) > -1) {
            end = index + highlight1.length();
            sp.setSpan(new QMUITouchableSpan(highlightTextNormalColor, highlightTextPressedColor,
                    highlightBgNormalColor, highlightBgPressedColor) {
                @Override
                public void onSpanClick(View widget) {
                    WebViewActivity.skip(RegisterActivity.this, Constent.USERPROTOCOL_URL, "注册协议");
                }
            }, index, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            start = end;
        }
        start = 0;
        while ((index = text.indexOf(highlight2, start)) > -1) {
            end = index + highlight2.length();
            sp.setSpan(new QMUITouchableSpan(highlightTextNormalColor, highlightTextPressedColor,
                    highlightBgNormalColor, highlightBgPressedColor) {
                @Override
                public void onSpanClick(View widget) {
                    WebViewActivity.skip(RegisterActivity.this, Constent.PRIVACYSERVICE_URL, "服务协议");
                }
            }, index, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            start = end;
        }
        start = 0;
        while ((index = text.indexOf(highlight3, start)) > -1) {
            end = index + highlight3.length();
            sp.setSpan(new QMUITouchableSpan(highlightTextNormalColor, highlightTextPressedColor,
                    highlightBgNormalColor, highlightBgPressedColor) {
                @Override
                public void onSpanClick(View widget) {
                    WebViewActivity.skip(RegisterActivity.this, Constent.PRIVACY_URL, "隐私政策");
                }
            }, index, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            start = end;
        }
        return sp;
    }
    //工具类1
    public class QMUIResHelper {

    public static float getAttrFloatValue(Context context, int attrRes){
        TypedValue typedValue = new TypedValue();
        context.getTheme().resolveAttribute(attrRes, typedValue, true);
        return typedValue.getFloat();
    }

    public static int getAttrColor(Context context, int attrRes){
        TypedValue typedValue = new TypedValue();
        context.getTheme().resolveAttribute(attrRes, typedValue, true);
        return typedValue.data;
    }
}
//工具2
/**
 * 可 Touch 的 Span,在 {@link #setPressed(boolean)} 后根据是否 pressed 来触发不同的UI状态
 * 

* 提供设置 span 的文字颜色和背景颜色的功能, 在构造时传入 *

*/ public abstract class QMUITouchableSpan extends ClickableSpan implements ITouchableSpan { private boolean mIsPressed; @ColorInt private int mNormalBackgroundColor; @ColorInt private int mPressedBackgroundColor; @ColorInt private int mNormalTextColor; @ColorInt private int mPressedTextColor; private boolean mIsNeedUnderline = false; public abstract void onSpanClick(View widget); @Override public final void onClick(View widget) { if (ViewCompat.isAttachedToWindow(widget)) { onSpanClick(widget); } } public QMUITouchableSpan(@ColorInt int normalTextColor, @ColorInt int pressedTextColor, @ColorInt int normalBackgroundColor, @ColorInt int pressedBackgroundColor) { mNormalTextColor = normalTextColor; mPressedTextColor = pressedTextColor; mNormalBackgroundColor = normalBackgroundColor; mPressedBackgroundColor = pressedBackgroundColor; } public int getNormalBackgroundColor() { return mNormalBackgroundColor; } public void setNormalTextColor(int normalTextColor) { mNormalTextColor = normalTextColor; } public void setPressedTextColor(int pressedTextColor) { mPressedTextColor = pressedTextColor; } public int getNormalTextColor() { return mNormalTextColor; } public int getPressedBackgroundColor() { return mPressedBackgroundColor; } public int getPressedTextColor() { return mPressedTextColor; } public void setPressed(boolean isSelected) { mIsPressed = isSelected; } public boolean isPressed() { return mIsPressed; } public void setIsNeedUnderline(boolean isNeedUnderline) { mIsNeedUnderline = isNeedUnderline; } @Override public void updateDrawState(TextPaint ds) { ds.setColor(mIsPressed ? mPressedTextColor : mNormalTextColor); ds.bgColor = mIsPressed ? mPressedBackgroundColor : mNormalBackgroundColor; ds.setUnderlineText(mIsNeedUnderline); } }

3.以上代码就可以完美实现Textview显示部分字体颜色更改并且跳转,好啦,代码也比较简单,就分享到这里,有任何问题欢迎留言!

你可能感兴趣的:(android)