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状态
 * <p>
 * 提供设置 span 的文字颜色和背景颜色的功能, 在构造时传入  ### implements ITouchableSpan 
 * </p>
 */
public abstract class QMUITouchableSpan extends ClickableSpan  {
    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显示部分字体颜色更改并且跳转,好啦,代码也比较简单,就分享到这里,有任何问题欢迎留言!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Kotlin 中,您可以使用 SpannableString 和 ClickableSpan 实现TextView 中设置不同字体大小、颜色点击事件的效果。下面是一个示例代码: ```otlin val text = "这是一个示例文本" val spannableString = SpannableString(text) // 设置部分文字的字体大小 val sizeSpan = RelativeSizeSpan(1.5f) // 放大1.5倍 spannableString.setSpan(sizeSpan, 2, 5, Spanned.SPAN_INCLUSIVE_INCLUSIVE) // 设置第2到第5个字符的字体大小 // 设置部分文字的颜色 val colorSpan = ForegroundColorSpan(Color.RED) spannableString.setSpan(colorSpan, 8, 10, Spanned.SPAN_INCLUSIVE_INCLUSIVE) // 设置第8到第10个字符的颜色 val textView = findViewById<TextView>(R.id.textView) textView.text = spannableString // 设置部分文字的点击事件 val clickableSpan = object : ClickableSpan() { override fun onClick(widget: View) { // 在这里处理点击事件 Toast.makeText(this@MainActivity, "点击事件触发了", Toast.LENGTH_SHORT).show() } } spannableString.setSpan(clickableSpan, 2, 4, Spanned.SPAN_INCLUSIVE_INCLUSIVE) // 设置第2到第4个字符的点击事件 textView.text = spannableString textView.movementMethod = LinkMovementMethod.getInstance() // 必须设置这个方法才能触发点击事件 ``` 上述代码中,我们创建了一个 SpannableString 对象,然后使用 setSpan() 方法来设置不同的 Span(包括字体大小、颜色点击事件)。最后,将 SpannableString 对象设置给 TextView 显示出来。 希望能对您有所帮助!如果您有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值