package org.wordpress.android.ui.notifications.blocks; import android.support.annotation.NonNull; import android.text.Layout; import android.text.Selection; import android.text.Spannable; import android.text.method.LinkMovementMethod; import android.view.MotionEvent; import android.widget.TextView; /** * Allows links to be highlighted when tapped on note blocks. * See: http://stackoverflow.com/a/20905824/309558 */ class NoteBlockLinkMovementMethod extends LinkMovementMethod { private NoteBlockClickableSpan mPressedSpan; @Override public boolean onTouchEvent(@NonNull TextView textView, @NonNull Spannable spannable, @NonNull 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) { NoteBlockClickableSpan 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 NoteBlockClickableSpan 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); NoteBlockClickableSpan[] link = spannable.getSpans(off, off, NoteBlockClickableSpan.class); NoteBlockClickableSpan touchedSpan = null; if (link.length > 0) { touchedSpan = link[0]; } return touchedSpan; } }