Last active
March 2, 2016 06:41
-
-
Save 4dcity/61d73d32c2ed09e44749 to your computer and use it in GitHub Desktop.
Change the text color of a single ClickableSpan when pressed without affecting other ClickableSpans in the same TextView
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.text.Layout; | |
import android.text.Selection; | |
import android.text.Spannable; | |
import android.text.TextPaint; | |
import android.text.method.LinkMovementMethod; | |
import android.text.style.CharacterStyle; | |
import android.text.style.UpdateAppearance; | |
import android.view.MotionEvent; | |
import android.view.View; | |
import android.widget.TextView; | |
private 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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 = pressedBackgroundColor; | |
} | |
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 : 0xffeeeeee; | |
ds.setUnderlineText(false); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment