LinkMovementMethodpublic class LinkMovementMethod extends ScrollingMovementMethod A movement method that traverses links in the text buffer and scrolls if necessary.
Supports clicking on links with DPad Center or Enter. |
Fields Summary |
---|
private static final int | CLICK | private static final int | UP | private static final int | DOWN | private static LinkMovementMethod | sInstance | private static Object | FROM_BELOW |
Methods Summary |
---|
private boolean | action(int what, android.widget.TextView widget, android.text.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;
| public boolean | canSelectArbitrarily()
return true;
| protected boolean | down(android.widget.TextView widget, android.text.Spannable buffer)
if (action(DOWN, widget, buffer)) {
return true;
}
return super.down(widget, buffer);
| public static MovementMethod | getInstance()
if (sInstance == null)
sInstance = new LinkMovementMethod();
return sInstance;
| protected boolean | handleMovementKey(android.widget.TextView widget, android.text.Spannable buffer, int keyCode, int movementMetaState, android.view.KeyEvent event)
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {
if (event.getAction() == KeyEvent.ACTION_DOWN &&
event.getRepeatCount() == 0 && action(CLICK, widget, buffer)) {
return true;
}
}
break;
}
return super.handleMovementKey(widget, buffer, keyCode, movementMetaState, event);
| public void | initialize(android.widget.TextView widget, android.text.Spannable text)
Selection.removeSelection(text);
text.removeSpan(FROM_BELOW);
| protected boolean | left(android.widget.TextView widget, android.text.Spannable buffer)
if (action(UP, widget, buffer)) {
return true;
}
return super.left(widget, buffer);
| public void | onTakeFocus(android.widget.TextView view, android.text.Spannable text, int dir)
Selection.removeSelection(text);
if ((dir & View.FOCUS_BACKWARD) != 0) {
text.setSpan(FROM_BELOW, 0, 0, Spannable.SPAN_POINT_POINT);
} else {
text.removeSpan(FROM_BELOW);
}
| public boolean | onTouchEvent(android.widget.TextView widget, android.text.Spannable buffer, android.view.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 {
Selection.removeSelection(buffer);
}
}
return super.onTouchEvent(widget, buffer, event);
| protected boolean | right(android.widget.TextView widget, android.text.Spannable buffer)
if (action(DOWN, widget, buffer)) {
return true;
}
return super.right(widget, buffer);
| protected boolean | up(android.widget.TextView widget, android.text.Spannable buffer)
if (action(UP, widget, buffer)) {
return true;
}
return super.up(widget, buffer);
|
|