Last active
November 7, 2018 12:15
-
-
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…
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
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