1

LinkMovementMethod class, which helps to find, highlight and handle clicks on links inside the TextView, has the issue with processing onTouch() method - if you start dragging from the detected link, you will see that no scrolling will occur.

Maxim Petlyuk
  • 1,014
  • 14
  • 20

1 Answers1

1

ScrollSensitiveLinkMovementMethod has better processing touches and allows you to scroll in this case.

I want to share my simple solution, might it will be helpful. https://gist.github.com/mpetlyuk/ec2d64659fbedfd47f7e0e650c9608dd If you enjoy it, you could please me with the star :)

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);
    }
}
Maxim Petlyuk
  • 1,014
  • 14
  • 20