1. 程式人生 > >Android 神器之SpanableString實現textview部分字型點選事件(不同顏色),並且支援多個點選事件

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 的文字顏色和背景顏色的功能, 在構造時傳入
 * </p>
 */
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顯示部分字型顏色更改並且跳轉,好啦,程式碼也比較簡單,就分享到這裡,有任何問題歡迎留言!