FileDocCategorySizeDatePackage
LinkMovementMethod.javaAPI DocAndroid 1.5 API7526Wed May 06 22:41:56 BST 2009android.text.method

LinkMovementMethod

public class LinkMovementMethod extends ScrollingMovementMethod

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
Constructors Summary
Methods Summary
private booleanaction(int what, android.widget.TextView widget, Spannable buffer)

        boolean handled = false;

        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;
    
protected booleandown(android.widget.TextView widget, Spannable buffer)

        if (action(DOWN, widget, buffer)) {
            return true;
        }

        return super.down(widget, buffer);
    
public static MovementMethodgetInstance()

        if (sInstance == null)
            sInstance = new LinkMovementMethod();

        return sInstance;
    
public voidinitialize(android.widget.TextView widget, Spannable text)

        Selection.removeSelection(text);
        text.removeSpan(FROM_BELOW);
    
protected booleanleft(android.widget.TextView widget, Spannable buffer)

        if (action(UP, widget, buffer)) {
            return true;
        }

        return super.left(widget, buffer);
    
public booleanonKeyDown(android.widget.TextView widget, Spannable buffer, int keyCode, android.view.KeyEvent event)


    
         
                                 
        switch (keyCode) {
        case KeyEvent.KEYCODE_DPAD_CENTER:
        case KeyEvent.KEYCODE_ENTER:
            if (event.getRepeatCount() == 0) {
                if (action(CLICK, widget, buffer)) {
                    return true;
                }
            }
        }

        return super.onKeyDown(widget, buffer, keyCode, event);
    
public booleanonKeyUp(android.widget.TextView widget, Spannable buffer, int keyCode, android.view.KeyEvent event)

        return false;
    
public voidonTakeFocus(android.widget.TextView view, 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 booleanonTouchEvent(android.widget.TextView widget, 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 booleanright(android.widget.TextView widget, Spannable buffer)

        if (action(DOWN, widget, buffer)) {
            return true;
        }

        return super.right(widget, buffer);
    
protected booleanup(android.widget.TextView widget, Spannable buffer)

        if (action(UP, widget, buffer)) {
            return true;
        }

        return super.up(widget, buffer);