@Override
    public boolean onTouch(View v, MotionEvent event) {
        Layout layout = ((TextView) v).getLayout();
        if (layout == null) {
            return false;
        }
        int x = (int) event.getX();
        int y = (int) event.getY();
        int line = layout.getLineForVertical(y);
        int offset = layout.getOffsetForHorizontal(line, x);
        TextView tv = (TextView) v;
        SpannableString value = SpannableString.valueOf(tv.getText());
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                MyURLSpan[] urlSpans = value.getSpans(0, value.length(), MyURLSpan.class);
                int findStart = 0;
                int findEnd = 0;
                for (MyURLSpan urlSpan : urlSpans) {
                    int start = value.getSpanStart(urlSpan);
                    int end = value.getSpanEnd(urlSpan);
                    if (start <= offset && offset <= end) {
                        find = true;
                        findStart = start;
                        findEnd = end;
                        break;
                    }
                }
                float lineWidth = layout.getLineWidth(line);
                find &= (lineWidth >= x);
                if (find) {
                    LongClickableLinkMovementMethod.getInstance().onTouchEvent(tv, value, event);
                    BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(0xFFE9E9E9);
                    value.setSpan(backgroundColorSpan, findStart, findEnd,
                            Spanned.SPAN_INCLUSIVE_INCLUSIVE);
                    //Android has a bug, sometime TextView wont change its value when you modify SpannableString,
                    // so you must setText again, test on Android 4.3 Nexus4
                    tv.setText(value);
                }
                return find;
            case MotionEvent.ACTION_MOVE:
                if (find) {
                    LongClickableLinkMovementMethod.getInstance().onTouchEvent(tv, value, event);
                }
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                if (find) {
                    LongClickableLinkMovementMethod.getInstance().onTouchEvent(tv, value, event);
                    LongClickableLinkMovementMethod.getInstance().removeLongClickCallback();
                    BackgroundColorSpan[] backgroundColorSpans = value
                            .getSpans(0, value.length(), BackgroundColorSpan.class);
                    for (BackgroundColorSpan backgroundColorSpan : backgroundColorSpans) {
                        value.removeSpan(backgroundColorSpan);
                    }
                    tv.setText(value);
                    find = false;
                }
                break;
        }
        return false;
    }
@Override
    public boolean onTouch(View v, MotionEvent event) {
        Layout layout = ((TextView) v).getLayout();
        if (layout == null) {
            return false;
        }
        int x = (int) event.getX();
        int y = (int) event.getY();
        int line = layout.getLineForVertical(y);
        int offset = layout.getOffsetForHorizontal(line, x);
        TextView tv = (TextView) v;
        SpannableString value = SpannableString.valueOf(tv.getText());
        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                MyURLSpan[] urlSpans = value.getSpans(0, value.length(), MyURLSpan.class);
                int findStart = 0;
                int findEnd = 0;
                for (MyURLSpan urlSpan : urlSpans) {
                    int start = value.getSpanStart(urlSpan);
                    int end = value.getSpanEnd(urlSpan);
                    if (start <= offset && offset <= end) {
                        find = true;
                        findStart = start;
                        findEnd = end;
                        break;
                    }
                }
                float lineWidth = layout.getLineWidth(line);
                find &= (lineWidth >= x);
                if (find) {
                    LongClickableLinkMovementMethod.getInstance().onTouchEvent(tv, value, event);
                    BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(0xFFE9E9E9);
                    value.setSpan(backgroundColorSpan, findStart, findEnd,
                            Spanned.SPAN_INCLUSIVE_INCLUSIVE);
                   
                   
                    tv.setText(value);
                }
                return find;
            case MotionEvent.ACTION_MOVE:
                if (find) {
                    LongClickableLinkMovementMethod.getInstance().onTouchEvent(tv, value, event);
                }
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                if (find) {
                    LongClickableLinkMovementMethod.getInstance().onTouchEvent(tv, value, event);
                    LongClickableLinkMovementMethod.getInstance().removeLongClickCallback();
                    BackgroundColorSpan[] backgroundColorSpans = value
                            .getSpans(0, value.length(), BackgroundColorSpan.class);
                    for (BackgroundColorSpan backgroundColorSpan : backgroundColorSpans) {
                        value.removeSpan(backgroundColorSpan);
                    }
                    tv.setText(value);
                    find = false;
                }
                break;
        }
        return false;
    }
@override public boolean ontouch(view v, motionevent event) { layout layout = ((textview) v).getlayout(); if (layout == null) { return false; } int x = (int) event.getx(); int y = (int) event.gety(); int line = layout.getlineforvertical(y); int offset = layout.getoffsetforhorizontal(line, x); textview tv = (textview) v; spannablestring value = spannablestring.valueof(tv.gettext()); switch (event.getactionmasked()) { case motionevent.action_down: myurlspan[] urlspans = value.getspans(0, value.length(), myurlspan.class); int findstart = 0; int findend = 0; for (myurlspan urlspan : urlspans) { int start = value.getspanstart(urlspan); int end = value.getspanend(urlspan); if (start <= offset && offset <= end) { find = true; findstart = start; findend = end; break; } } float linewidth = layout.getlinewidth(line); find &= (linewidth >= x); if (find) { longclickablelinkmovementmethod.getinstance().ontouchevent(tv, value, event); backgroundcolorspan backgroundcolorspan = new backgroundcolorspan(0xffe9e9e9); value.setspan(backgroundcolorspan, findstart, findend, spanned.span_inclusive_inclusive); tv.settext(value); } return find; case motionevent.action_move: if (find) { longclickablelinkmovementmethod.getinstance().ontouchevent(tv, value, event); } break; case motionevent.action_cancel: case motionevent.action_up: if (find) { longclickablelinkmovementmethod.getinstance().ontouchevent(tv, value, event); longclickablelinkmovementmethod.getinstance().removelongclickcallback(); backgroundcolorspan[] backgroundcolorspans = value .getspans(0, value.length(), backgroundcolorspan.class); for (backgroundcolorspan backgroundcolorspan : backgroundcolorspans) { value.removespan(backgroundcolorspan); } tv.settext(value); find = false; } break; } return false; }