gerhard
gerhard

Reputation: 479

Have different colors for different hyperlinks within an Android Textview

I know that i can change the color of hyperlinks at the level of a textview by setting:

yourText.setLinkTextColor(Color.RED);

Within a Textview I can have multiple hyperlinks in my app. I would like to define a different color for each hyperlink-text. Using <font color ...>does not work unfortunately.

Any ideas?
Thanks!

Upvotes: 1

Views: 721

Answers (1)

karandeep singh
karandeep singh

Reputation: 2334

 String myString = "I accept the Terms of Use, Privacy Policy and I agree";
    SpannableString ss = new SpannableString(myString);
    ClickableSpan clickableSpan = new TouchableSpan(normalColor, touchColor, pressedColor) {
        @Override
        public void onClick(View widget) {
            //perform your action to open webview or whatever
        }
    };
    ClickableSpan clickableSpan2 = new TouchableSpan(normalColor, touchColor, pressedColor) {
        @Override
        public void onClick(View widget) {
            //perform your action to open webview or whatever
        }
    };
    ss.setSpan(clickableSpan, 13, 25, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    ss.setSpan(clickableSpan2, 26, 41, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    textView.text = ss;
    textView.movementMethod =new LinkTouchMovementMethod();

Explanation

 ss.setSpan(clickableSpan, 13, 25, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

This will make

Terms of Use

clickable. Similarly, the second span will make

privacy policy

clickable in my sample string. You can use the normal color,touchColor and pressedColor according to your needs.

TouchableSpan.java

public abstract class TouchableSpan extends ClickableSpan {
private boolean mIsPressed;
private int mPressedBackgroundColor;
private int mNormalTextColor;
private int mPressedTextColor;

public TouchableSpan(int normalTextColor, int pressedTextColor, int pressedBackgroundColor) {
    mNormalTextColor = normalTextColor;
    mPressedTextColor = pressedTextColor;
    mPressedBackgroundColor = 0xffeeeeee;
}

public void setPressed(boolean isSelected) {
    mIsPressed = isSelected;
}

@Override
public void updateDrawState(TextPaint ds) {
    super.updateDrawState(ds);
    ds.setColor(mIsPressed ? mPressedTextColor : mNormalTextColor);
    ds.bgColor = mIsPressed ? mPressedBackgroundColor : Color.TRANSPARENT;
    ds.setUnderlineText(false);
}
}

LinkTouchMovementMethod.java

public class LinkTouchMovementMethod extends LinkMovementMethod {
private TouchableSpan mPressedSpan;

@Override
public boolean onTouchEvent(TextView textView, Spannable spannable, MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        mPressedSpan = getPressedSpan(textView, spannable, event);
        if (mPressedSpan != null) {
            mPressedSpan.setPressed(true);
            Selection.setSelection(spannable, spannable.getSpanStart(mPressedSpan),
                    spannable.getSpanEnd(mPressedSpan));
        }
    } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
        TouchableSpan touchedSpan = getPressedSpan(textView, spannable, event);
        if (mPressedSpan != null && touchedSpan != mPressedSpan) {
            mPressedSpan.setPressed(false);
            mPressedSpan = null;
            Selection.removeSelection(spannable);
        }
    } else {
        if (mPressedSpan != null) {
            mPressedSpan.setPressed(false);
            super.onTouchEvent(textView, spannable, event);
        }
        mPressedSpan = null;
        Selection.removeSelection(spannable);
    }
    return true;
}

private TouchableSpan getPressedSpan(TextView textView, Spannable spannable, MotionEvent
        event) {

    int x = (int) event.getX();
    int y = (int) event.getY();

    x -= textView.getTotalPaddingLeft();
    y -= textView.getTotalPaddingTop();

    x += textView.getScrollX();
    y += textView.getScrollY();

    Layout layout = textView.getLayout();
    int line = layout.getLineForVertical(y);
    int off = layout.getOffsetForHorizontal(line, x);

    TouchableSpan[] link = spannable.getSpans(off, off, TouchableSpan.class);
    TouchableSpan touchedSpan = null;
    if (link.length > 0) {
        touchedSpan = link[0];
    }
    return touchedSpan;
}

 }

Upvotes: 1

Related Questions