Skip to content

Instantly share code, notes, and snippets.

@maxim-petlyuk
Last active November 7, 2018 12:15
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maxim-petlyuk/ec2d64659fbedfd47f7e0e650c9608dd to your computer and use it in GitHub Desktop.
Save maxim-petlyuk/ec2d64659fbedfd47f7e0e650c9608dd to your computer and use it in GitHub Desktop.
LinkMovementMethod class, which helps to find, highlight and handle clicks on links inside the TextView, has the issue with processing onTouch() method - if you tap on the link and try to scroll the textview, you will see that no scrolling will occur. ScrollSensitiveLinkMovementMethod has better processing touches and allows you to scroll even i…
package your_package_name;
import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.text.method.Touch;
import android.text.style.ClickableSpan;
import android.view.MotionEvent;
import android.widget.TextView;
public class ScrollSensitiveLinkMovementMethod extends LinkMovementMethod {
private int CLICK_ACTION_THRESHOLD = 100;
private float startX;
private float startY;
private boolean isAClick(float startX, float endX, float startY, float endY) {
float differenceX = Math.abs(startX - endX);
float differenceY = Math.abs(startY - endY);
return !(differenceX > CLICK_ACTION_THRESHOLD || differenceY > CLICK_ACTION_THRESHOLD);
}
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer,
MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();
case MotionEvent.ACTION_UP:
float endX = event.getX();
float endY = event.getY();
int x = (int) event.getX();
int y = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
ClickableSpan[] links = buffer.getSpans(off, off, ClickableSpan.class);
if (links.length != 0) {
if (action == MotionEvent.ACTION_UP && isAClick(startX, endX, startY, endY)) {
links[0].onClick(widget);
return true;
} else {
Selection.setSelection(buffer,
buffer.getSpanStart(links[0]),
buffer.getSpanEnd(links[0]));
}
} else {
Selection.removeSelection(buffer);
}
break;
}
return Touch.onTouchEvent(widget, buffer, event);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment