Java Code Examples for android.widget.TextView#getScrollY()
The following examples show how to use
android.widget.TextView#getScrollY() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ClickableMovementMethod.java From Conversations with GNU General Public License v3.0 | 6 votes |
@Override public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { // Just copied from android.text.method.LinkMovementMethod if (event.getAction() == MotionEvent.ACTION_UP) { 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[] link = buffer.getSpans(off, off, ClickableSpan.class); if (link.length != 0) { link[0].onClick(widget); return true; } } return super.onTouchEvent(widget, buffer, event); }
Example 2
Source File: LinkTouchMovementMethod.java From android-proguards with Apache License 2.0 | 6 votes |
private TouchableUrlSpan 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); TouchableUrlSpan[] link = spannable.getSpans(off, off, TouchableUrlSpan.class); TouchableUrlSpan touchedSpan = null; if (link.length > 0) { touchedSpan = link[0]; } return touchedSpan; }
Example 3
Source File: ClickableMovementMethod.java From Pix-Art-Messenger with GNU General Public License v3.0 | 6 votes |
@Override public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { // Just copied from android.text.method.LinkMovementMethod if (event.getAction() == MotionEvent.ACTION_UP) { 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[] link = buffer.getSpans(off, off, ClickableSpan.class); if (link.length != 0) { link[0].onClick(widget); return true; } } return super.onTouchEvent(widget, buffer, event); }
Example 4
Source File: LinkTouchMovementMethod.java From materialup with Apache License 2.0 | 6 votes |
private TouchableUrlSpan 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); TouchableUrlSpan[] link = spannable.getSpans(off, off, TouchableUrlSpan.class); TouchableUrlSpan touchedSpan = null; if (link.length > 0) { touchedSpan = link[0]; } return touchedSpan; }
Example 5
Source File: LinkTextView.java From LinkTextView with MIT License | 6 votes |
private TouchableSpan 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); TouchableSpan[] link = spannable.getSpans(off, off, TouchableSpan.class); TouchableSpan touchedSpan = null; if (link.length > 0) { touchedSpan = link[0]; } return touchedSpan; }
Example 6
Source File: LongClickableLinkMovementMethod.java From RichEditor with MIT License | 6 votes |
private BlockImageSpan getPressedSpan(TextView textView, Spannable spannable, MotionEvent event) { int x = (int) event.getX() - textView.getTotalPaddingLeft() + textView.getScrollX(); int y = (int) event.getY() - textView.getTotalPaddingTop() + textView.getScrollY(); Layout layout = textView.getLayout(); int position = layout.getOffsetForHorizontal(layout.getLineForVertical(y), x); BlockImageSpan[] blockImageSpans = spannable.getSpans(position, position, BlockImageSpan.class); BlockImageSpan touchedSpan = null; if (blockImageSpans.length > 0 && positionWithinTag(position, spannable, blockImageSpans[0]) && blockImageSpans[0].clicked(x, y)) { touchedSpan = blockImageSpans[0]; } return touchedSpan; }
Example 7
Source File: QBMessageTextClickMovement.java From ChatMessagesAdapter-android with BSD 3-Clause "New" or "Revised" License | 6 votes |
private String getLinkText(final TextView widget, final Spannable buffer, final MotionEvent event) { 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[] link = buffer.getSpans(off, off, ClickableSpan.class); if (link.length != 0) { return buffer.subSequence(buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0])).toString(); } return buffer.toString(); }
Example 8
Source File: NameTouchMovementMethod.java From meiShi with Apache License 2.0 | 5 votes |
private int getOffsetForHorizontal(TextView widget, MotionEvent event) { 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); return layout.getOffsetForHorizontal(line, x); }
Example 9
Source File: SelectableLinkMovementMethod.java From mimi-reader with Apache License 2.0 | 5 votes |
@Override public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { 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[] link = buffer.getSpans(off, off, ClickableSpan.class); if (link.length != 0) { if (action == MotionEvent.ACTION_UP) { link[0].onClick(widget); } else if (action == MotionEvent.ACTION_DOWN) { Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0])); } return true; } /*else { that's the line we need to remove Selection.removeSelection(buffer); }*/ } return super.onTouchEvent(widget, buffer, event); }
Example 10
Source File: LineUtils.java From CodeEditor with Apache License 2.0 | 5 votes |
public int getTopVisibleLine(TextView editor) { int lineHeight = editor.getLineHeight(); if (lineHeight == 0) { return 0; } int line = editor.getScrollY() / lineHeight; if (line < 0) { return 0; } if (line >= editor.getLineCount()) { return editor.getLineCount() - 1; } return line; }
Example 11
Source File: EmojiconTextView.java From imsdk-android with MIT License | 5 votes |
private boolean handleLinkMovementMethod(TextView widget, Spannable buffer, MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { 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[] link = buffer.getSpans(off, off, ClickableSpan.class); if (link.length != 0) { if (action == MotionEvent.ACTION_UP) { long actionUpTime = System.currentTimeMillis(); if (actionUpTime - mLastActionDownTime > ViewConfiguration.getLongPressTimeout()) { //长按事件,取消LinkMovementMethod处理,即不处理ClickableSpan点击事件 return false; } link[0].onClick(widget); Selection.removeSelection(buffer); } else if (action == MotionEvent.ACTION_DOWN) { Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0])); mLastActionDownTime = System.currentTimeMillis(); } } } return false; }
Example 12
Source File: LinkMovementClickMethod.java From imsdk-android with MIT License | 5 votes |
@Override public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { 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[] link = buffer.getSpans(off, off, ClickableSpan.class); if (link.length != 0) { if (action == MotionEvent.ACTION_UP) { if(System.currentTimeMillis() - lastClickTime < CLICK_DELAY){ link[0].onClick(widget); } } else if (action == MotionEvent.ACTION_DOWN) { Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0])); lastClickTime = System.currentTimeMillis(); } return true; } else { Selection.removeSelection(buffer); } } return super.onTouchEvent(widget, buffer, event); }
Example 13
Source File: CustomMoveMethod.java From NewFastFrame with Apache License 2.0 | 4 votes |
@Override public boolean onTouchEvent(TextView widget, Spannable text, MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: // 这里得到的x , y值只是相对于屏幕的位置 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 location = layout.getOffsetForHorizontal(layout.getLineForVertical(y), x); clickableSpans = text.getSpans(location, location, ClickableSpan.class); if (clickableSpans.length > 0) { isClickTextView = false; LogUtil.e("点击clickSpan位置"); // 选中点击位置 // Selection.setSelection(text, text.getSpanStart(clickableSpans[0]), text.getSpanEnd(clickableSpans[0])); text.setSpan(colorSpan = new BackgroundColorSpan(selectedColor), text.getSpanStart(clickableSpans[0]), text.getSpanEnd(clickableSpans[0]), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); return true; } else { isClickTextView = true; } break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: if (clickableSpans.length > 0) { LogUtil.e("点击span的up11"); // 设置点击时间 clickableSpans[0].onClick(widget); text.removeSpan(colorSpan); // Selection.removeSelection(text); return true; } else { LogUtil.e("点击textView文字的up11"); } break; default: if (colorSpan != null) { text.removeSpan(colorSpan); // Selection.removeSelection(text); return true; } break; } return super.onTouchEvent(widget, text, event); }
Example 14
Source File: LongClickMovementMethod.java From mollyim-android with GNU General Public License v3.0 | 4 votes |
@Override public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { 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); LongClickCopySpan longClickCopySpan[] = buffer.getSpans(off, off, LongClickCopySpan.class); if (longClickCopySpan.length != 0) { LongClickCopySpan aSingleSpan = longClickCopySpan[0]; if (action == MotionEvent.ACTION_DOWN) { Selection.setSelection(buffer, buffer.getSpanStart(aSingleSpan), buffer.getSpanEnd(aSingleSpan)); aSingleSpan.setHighlighted(true, ContextCompat.getColor(widget.getContext(), R.color.touch_highlight)); } else { Selection.removeSelection(buffer); aSingleSpan.setHighlighted(false, Color.TRANSPARENT); } this.currentSpan = aSingleSpan; this.widget = widget; return gestureDetector.onTouchEvent(event); } } else if (action == MotionEvent.ACTION_CANCEL) { // Remove Selections. LongClickCopySpan[] spans = buffer.getSpans(Selection.getSelectionStart(buffer), Selection.getSelectionEnd(buffer), LongClickCopySpan.class); for (LongClickCopySpan aSpan : spans) { aSpan.setHighlighted(false, Color.TRANSPARENT); } Selection.removeSelection(buffer); return gestureDetector.onTouchEvent(event); } return super.onTouchEvent(widget, buffer, event); }
Example 15
Source File: MyLinkMovementMethod.java From FoldText_Java with MIT License | 4 votes |
private boolean action(int what, TextView widget, Spannable buffer) { Layout layout = widget.getLayout(); int padding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom(); int areaTop = widget.getScrollY(); int areaBot = areaTop + widget.getHeight() - padding; int lineTop = layout.getLineForVertical(areaTop); int lineBot = layout.getLineForVertical(areaBot); int first = layout.getLineStart(lineTop); int last = layout.getLineEnd(lineBot); ClickableSpan[] candidates = buffer.getSpans(first, last, ClickableSpan.class); int a = Selection.getSelectionStart(buffer); int b = Selection.getSelectionEnd(buffer); int selStart = Math.min(a, b); int selEnd = Math.max(a, b); if (selStart < 0) { if (buffer.getSpanStart(FROM_BELOW) >= 0) { selStart = selEnd = buffer.length(); } } if (selStart > last) selStart = selEnd = Integer.MAX_VALUE; if (selEnd < first) selStart = selEnd = -1; switch (what) { case CLICK: if (selStart == selEnd) { return false; } ClickableSpan[] link = buffer.getSpans(selStart, selEnd, ClickableSpan.class); if (link.length != 1) return false; link[0].onClick(widget); break; case UP: int bestStart, bestEnd; bestStart = -1; bestEnd = -1; for (int i = 0; i < candidates.length; i++) { int end = buffer.getSpanEnd(candidates[i]); if (end < selEnd || selStart == selEnd) { if (end > bestEnd) { bestStart = buffer.getSpanStart(candidates[i]); bestEnd = end; } } } if (bestStart >= 0) { Selection.setSelection(buffer, bestEnd, bestStart); return true; } break; case DOWN: bestStart = Integer.MAX_VALUE; bestEnd = Integer.MAX_VALUE; for (int i = 0; i < candidates.length; i++) { int start = buffer.getSpanStart(candidates[i]); if (start > selStart || selStart == selEnd) { if (start < bestStart) { bestStart = start; bestEnd = buffer.getSpanEnd(candidates[i]); } } } if (bestEnd < Integer.MAX_VALUE) { Selection.setSelection(buffer, bestStart, bestEnd); return true; } break; } return false; }
Example 16
Source File: LinkMovementMethod2.java From Nimingban with Apache License 2.0 | 4 votes |
private boolean action(int what, TextView widget, Spannable buffer) { Layout layout = widget.getLayout(); int padding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom(); int areatop = widget.getScrollY(); int areabot = areatop + widget.getHeight() - padding; int linetop = layout.getLineForVertical(areatop); int linebot = layout.getLineForVertical(areabot); int first = layout.getLineStart(linetop); int last = layout.getLineEnd(linebot); ClickableSpan[] candidates = buffer.getSpans(first, last, ClickableSpan.class); int a = Selection.getSelectionStart(buffer); int b = Selection.getSelectionEnd(buffer); int selStart = Math.min(a, b); int selEnd = Math.max(a, b); if (selStart < 0) { if (buffer.getSpanStart(FROM_BELOW) >= 0) { selStart = selEnd = buffer.length(); } } if (selStart > last) selStart = selEnd = Integer.MAX_VALUE; if (selEnd < first) selStart = selEnd = -1; switch (what) { case CLICK: if (selStart == selEnd) { return false; } ClickableSpan[] link = buffer.getSpans(selStart, selEnd, ClickableSpan.class); if (link.length != 1) return false; link[0].onClick(widget); break; case UP: int beststart, bestend; beststart = -1; bestend = -1; for (int i = 0; i < candidates.length; i++) { int end = buffer.getSpanEnd(candidates[i]); if (end < selEnd || selStart == selEnd) { if (end > bestend) { beststart = buffer.getSpanStart(candidates[i]); bestend = end; } } } if (beststart >= 0) { Selection.setSelection(buffer, bestend, beststart); return true; } break; case DOWN: beststart = Integer.MAX_VALUE; bestend = Integer.MAX_VALUE; for (int i = 0; i < candidates.length; i++) { int start = buffer.getSpanStart(candidates[i]); if (start > selStart || selStart == selEnd) { if (start < beststart) { beststart = start; bestend = buffer.getSpanEnd(candidates[i]); } } } if (bestend < Integer.MAX_VALUE) { Selection.setSelection(buffer, beststart, bestend); return true; } break; } return false; }
Example 17
Source File: LongClickableLinkMovementMethod.java From RichText with MIT License | 4 votes |
@Override public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { 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); LongClickableSpan[] link = buffer.getSpans(off, off, LongClickableSpan.class); if (link.length != 0) { long currTime = System.currentTimeMillis(); LongClickableSpan l = link[0]; int ls = buffer.getSpanStart(l); int le = buffer.getSpanEnd(l); // 判断点击的点是否在Image范围内 ClickableImageSpan[] is = buffer.getSpans(ls, le, ClickableImageSpan.class); if (is.length > 0) { if (!is[0].clicked(x)) { Selection.removeSelection(buffer); return false; } } else if (off < layout.getOffsetToLeftOf(ls) || off > layout.getOffsetToLeftOf(le + 1)) { // 判断点击位置是否在链接范围内 Selection.removeSelection(buffer); return false; } if (action == MotionEvent.ACTION_UP) { // 如果按下时间超过500毫秒,触发长按事件 if (currTime - lastTime > MIN_INTERVAL) { if (!l.onLongClick(widget)) { // onLongClick返回false代表事件未处理,交由onClick处理 l.onClick(widget); } } else { l.onClick(widget); } } else { Selection.setSelection(buffer, ls, le); } lastTime = currTime; return true; } else { Selection.removeSelection(buffer); return false; } } return super.onTouchEvent(widget, buffer, event); }
Example 18
Source File: LongClickableLinkMovementMethod.java From iBeebo with GNU General Public License v3.0 | 4 votes |
private boolean action(int what, TextView widget, Spannable buffer) { Layout layout = widget.getLayout(); int padding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom(); int areatop = widget.getScrollY(); int areabot = areatop + widget.getHeight() - padding; int linetop = layout.getLineForVertical(areatop); int linebot = layout.getLineForVertical(areabot); int first = layout.getLineStart(linetop); int last = layout.getLineEnd(linebot); MyURLSpan[] candidates = buffer.getSpans(first, last, MyURLSpan.class); int a = Selection.getSelectionStart(buffer); int b = Selection.getSelectionEnd(buffer); int selStart = Math.min(a, b); int selEnd = Math.max(a, b); if (selStart < 0) { if (buffer.getSpanStart(FROM_BELOW) >= 0) { selStart = selEnd = buffer.length(); } } if (selStart > last) { selStart = selEnd = Integer.MAX_VALUE; } if (selEnd < first) { selStart = selEnd = -1; } switch (what) { case CLICK: if (selStart == selEnd) { return false; } MyURLSpan[] link = buffer.getSpans(selStart, selEnd, MyURLSpan.class); if (link.length != 1) { return false; } link[0].onClick(widget); break; case UP: int best_start = -1; int best_end = -1; for (MyURLSpan candidate1 : candidates) { int end = buffer.getSpanEnd(candidate1); if (end < selEnd || selStart == selEnd) { if (end > best_end) { best_start = buffer.getSpanStart(candidate1); best_end = end; } } } if (best_start >= 0) { Selection.setSelection(buffer, best_end, best_start); return true; } break; case DOWN: best_start = Integer.MAX_VALUE; best_end = Integer.MAX_VALUE; for (MyURLSpan candidate : candidates) { int start = buffer.getSpanStart(candidate); if (start > selStart || selStart == selEnd) { if (start < best_start) { best_start = start; best_end = buffer.getSpanEnd(candidate); } } } if (best_end < Integer.MAX_VALUE) { Selection.setSelection(buffer, best_start, best_end); return true; } break; } return false; }
Example 19
Source File: LinkMovementMethod.java From android_9.0.0_r45 with Apache License 2.0 | 4 votes |
@Override public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { 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) { ClickableSpan link = links[0]; if (action == MotionEvent.ACTION_UP) { if (link instanceof TextLinkSpan) { ((TextLinkSpan) link).onClick( widget, TextLinkSpan.INVOCATION_METHOD_TOUCH); } else { link.onClick(widget); } } else if (action == MotionEvent.ACTION_DOWN) { if (widget.getContext().getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.P) { // Selection change will reposition the toolbar. Hide it for a few ms for a // smoother transition. widget.hideFloatingToolbar(HIDE_FLOATING_TOOLBAR_DELAY_MS); } Selection.setSelection(buffer, buffer.getSpanStart(link), buffer.getSpanEnd(link)); } return true; } else { Selection.removeSelection(buffer); } } return super.onTouchEvent(widget, buffer, event); }
Example 20
Source File: LinkMovementMethod2.java From EhViewer with Apache License 2.0 | 4 votes |
private boolean action(int what, TextView widget, Spannable buffer) { Layout layout = widget.getLayout(); int padding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom(); int areatop = widget.getScrollY(); int areabot = areatop + widget.getHeight() - padding; int linetop = layout.getLineForVertical(areatop); int linebot = layout.getLineForVertical(areabot); int first = layout.getLineStart(linetop); int last = layout.getLineEnd(linebot); ClickableSpan[] candidates = buffer.getSpans(first, last, ClickableSpan.class); int a = Selection.getSelectionStart(buffer); int b = Selection.getSelectionEnd(buffer); int selStart = Math.min(a, b); int selEnd = Math.max(a, b); if (selStart < 0) { if (buffer.getSpanStart(FROM_BELOW) >= 0) { selStart = selEnd = buffer.length(); } } if (selStart > last) selStart = selEnd = Integer.MAX_VALUE; if (selEnd < first) selStart = selEnd = -1; switch (what) { case CLICK: if (selStart == selEnd) { return false; } ClickableSpan[] link = buffer.getSpans(selStart, selEnd, ClickableSpan.class); if (link.length != 1) return false; link[0].onClick(widget); break; case UP: int beststart, bestend; beststart = -1; bestend = -1; for (int i = 0; i < candidates.length; i++) { int end = buffer.getSpanEnd(candidates[i]); if (end < selEnd || selStart == selEnd) { if (end > bestend) { beststart = buffer.getSpanStart(candidates[i]); bestend = end; } } } if (beststart >= 0) { Selection.setSelection(buffer, bestend, beststart); return true; } break; case DOWN: beststart = Integer.MAX_VALUE; bestend = Integer.MAX_VALUE; for (int i = 0; i < candidates.length; i++) { int start = buffer.getSpanStart(candidates[i]); if (start > selStart || selStart == selEnd) { if (start < beststart) { beststart = start; bestend = buffer.getSpanEnd(candidates[i]); } } } if (bestend < Integer.MAX_VALUE) { Selection.setSelection(buffer, beststart, bestend); return true; } break; } return false; }