FileDocCategorySizeDatePackage
ArrowKeyMovementMethod.javaAPI DocAndroid 5.1 API13221Thu Mar 12 22:22:10 GMT 2015android.text.method

ArrowKeyMovementMethod

public class ArrowKeyMovementMethod extends BaseMovementMethod implements MovementMethod
A movement method that provides cursor movement and selection. Supports displaying the context menu on DPad Center.

Fields Summary
private static final Object
LAST_TAP_DOWN
private static ArrowKeyMovementMethod
sInstance
Constructors Summary
Methods Summary
protected booleanbottom(android.widget.TextView widget, android.text.Spannable buffer)

        if (isSelecting(buffer)) {
            Selection.extendSelection(buffer, buffer.length());
        } else {
            Selection.setSelection(buffer, buffer.length());
        }
        return true;
    
public booleancanSelectArbitrarily()

        return true;
    
protected booleandown(android.widget.TextView widget, android.text.Spannable buffer)

        final Layout layout = widget.getLayout();
        if (isSelecting(buffer)) {
            return Selection.extendDown(buffer, layout);
        } else {
            return Selection.moveDown(buffer, layout);
        }
    
protected booleanend(android.widget.TextView widget, android.text.Spannable buffer)

        return lineEnd(widget, buffer);
    
private static intgetCurrentLineTop(android.text.Spannable buffer, android.text.Layout layout)

        return layout.getLineTop(layout.getLineForOffset(Selection.getSelectionEnd(buffer)));
    
public static MovementMethodgetInstance()

        if (sInstance == null) {
            sInstance = new ArrowKeyMovementMethod();
        }

        return sInstance;
    
private static intgetPageHeight(android.widget.TextView widget)

        // This calculation does not take into account the view transformations that
        // may have been applied to the child or its containers.  In case of scaling or
        // rotation, the calculated page height may be incorrect.
        final Rect rect = new Rect();
        return widget.getGlobalVisibleRect(rect) ? rect.height() : 0;
    
protected booleanhandleMovementKey(android.widget.TextView widget, android.text.Spannable buffer, int keyCode, int movementMetaState, android.view.KeyEvent event)

        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_CENTER:
                if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {
                    if (event.getAction() == KeyEvent.ACTION_DOWN
                            && event.getRepeatCount() == 0
                            && MetaKeyKeyListener.getMetaState(buffer,
                                        MetaKeyKeyListener.META_SELECTING, event) != 0) {
                        return widget.showContextMenu();
                    }
                }
                break;
        }
        return super.handleMovementKey(widget, buffer, keyCode, movementMetaState, event);
    
protected booleanhome(android.widget.TextView widget, android.text.Spannable buffer)

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

        Selection.setSelection(text, 0);
    
private static booleanisSelecting(android.text.Spannable buffer)

        return ((MetaKeyKeyListener.getMetaState(buffer, MetaKeyKeyListener.META_SHIFT_ON) == 1) ||
                (MetaKeyKeyListener.getMetaState(buffer, MetaKeyKeyListener.META_SELECTING) != 0));
    
private static booleanisTouchSelecting(boolean isMouse, android.text.Spannable buffer)

        return isMouse ? Touch.isActivelySelecting(buffer) : isSelecting(buffer);
    
protected booleanleft(android.widget.TextView widget, android.text.Spannable buffer)

        final Layout layout = widget.getLayout();
        if (isSelecting(buffer)) {
            return Selection.extendLeft(buffer, layout);
        } else {
            return Selection.moveLeft(buffer, layout);
        }
    
protected booleanleftWord(android.widget.TextView widget, android.text.Spannable buffer)
{@hide}

        final int selectionEnd = widget.getSelectionEnd();
        final WordIterator wordIterator = widget.getWordIterator();
        wordIterator.setCharSequence(buffer, selectionEnd, selectionEnd);
        return Selection.moveToPreceding(buffer, wordIterator, isSelecting(buffer));
    
protected booleanlineEnd(android.widget.TextView widget, android.text.Spannable buffer)

        final Layout layout = widget.getLayout();
        if (isSelecting(buffer)) {
            return Selection.extendToRightEdge(buffer, layout);
        } else {
            return Selection.moveToRightEdge(buffer, layout);
        }
    
protected booleanlineStart(android.widget.TextView widget, android.text.Spannable buffer)

        final Layout layout = widget.getLayout();
        if (isSelecting(buffer)) {
            return Selection.extendToLeftEdge(buffer, layout);
        } else {
            return Selection.moveToLeftEdge(buffer, layout);
        }
    
public voidonTakeFocus(android.widget.TextView view, android.text.Spannable text, int dir)

        if ((dir & (View.FOCUS_FORWARD | View.FOCUS_DOWN)) != 0) {
            if (view.getLayout() == null) {
                // This shouldn't be null, but do something sensible if it is.
                Selection.setSelection(text, text.length());
            }
        } else {
            Selection.setSelection(text, text.length());
        }
    
public booleanonTouchEvent(android.widget.TextView widget, android.text.Spannable buffer, android.view.MotionEvent event)

        int initialScrollX = -1;
        int initialScrollY = -1;
        final int action = event.getAction();
        final boolean isMouse = event.isFromSource(InputDevice.SOURCE_MOUSE);

        if (action == MotionEvent.ACTION_UP) {
            initialScrollX = Touch.getInitialScrollX(widget, buffer);
            initialScrollY = Touch.getInitialScrollY(widget, buffer);
        }

        boolean handled = Touch.onTouchEvent(widget, buffer, event);

        if (widget.isFocused() && !widget.didTouchFocusSelect()) {
            if (action == MotionEvent.ACTION_DOWN) {
                // Capture the mouse pointer down location to ensure selection starts
                // right under the mouse (and is not influenced by cursor location).
                // The code below needs to run for mouse events.
                // For touch events, the code should run only when selection is active.
                if (isMouse || isTouchSelecting(isMouse, buffer)) {
                    int offset = widget.getOffsetForPosition(event.getX(), event.getY());
                    buffer.setSpan(LAST_TAP_DOWN, offset, offset, Spannable.SPAN_POINT_POINT);
                    // Disallow intercepting of the touch events, so that
                    // users can scroll and select at the same time.
                    // without this, users would get booted out of select
                    // mode once the view detected it needed to scroll.
                    widget.getParent().requestDisallowInterceptTouchEvent(true);
                }
            } else if (action == MotionEvent.ACTION_MOVE) {

                // Cursor can be active at any location in the text while mouse pointer can start
                // selection from a totally different location. Use LAST_TAP_DOWN span to ensure
                // text selection will start from mouse pointer location.
                if (isMouse && Touch.isSelectionStarted(buffer)) {
                    int offset = buffer.getSpanStart(LAST_TAP_DOWN);
                    Selection.setSelection(buffer, offset);
                }

                if (isTouchSelecting(isMouse, buffer) && handled) {
                    // Before selecting, make sure we've moved out of the "slop".
                    // handled will be true, if we're in select mode AND we're
                    // OUT of the slop

                    // Turn long press off while we're selecting. User needs to
                    // re-tap on the selection to enable long press
                    widget.cancelLongPress();

                    // Update selection as we're moving the selection area.

                    // Get the current touch position
                    int offset = widget.getOffsetForPosition(event.getX(), event.getY());

                    Selection.extendSelection(buffer, offset);
                    return true;
                }
            } else if (action == MotionEvent.ACTION_UP) {
                // If we have scrolled, then the up shouldn't move the cursor,
                // but we do need to make sure the cursor is still visible at
                // the current scroll offset to avoid the scroll jumping later
                // to show it.
                if ((initialScrollY >= 0 && initialScrollY != widget.getScrollY()) ||
                    (initialScrollX >= 0 && initialScrollX != widget.getScrollX())) {
                    widget.moveCursorToVisibleOffset();
                    return true;
                }

                int offset = widget.getOffsetForPosition(event.getX(), event.getY());
                if (isTouchSelecting(isMouse, buffer)) {
                    buffer.removeSpan(LAST_TAP_DOWN);
                    Selection.extendSelection(buffer, offset);
                }

                MetaKeyKeyListener.adjustMetaAfterKeypress(buffer);
                MetaKeyKeyListener.resetLockedMeta(buffer);

                return true;
            }
        }
        return handled;
    
protected booleanpageDown(android.widget.TextView widget, android.text.Spannable buffer)

        final Layout layout = widget.getLayout();
        final boolean selecting = isSelecting(buffer);
        final int targetY = getCurrentLineTop(buffer, layout) + getPageHeight(widget);
        boolean handled = false;
        for (;;) {
            final int previousSelectionEnd = Selection.getSelectionEnd(buffer);
            if (selecting) {
                Selection.extendDown(buffer, layout);
            } else {
                Selection.moveDown(buffer, layout);
            }
            if (Selection.getSelectionEnd(buffer) == previousSelectionEnd) {
                break;
            }
            handled = true;
            if (getCurrentLineTop(buffer, layout) >= targetY) {
                break;
            }
        }
        return handled;
    
protected booleanpageUp(android.widget.TextView widget, android.text.Spannable buffer)

        final Layout layout = widget.getLayout();
        final boolean selecting = isSelecting(buffer);
        final int targetY = getCurrentLineTop(buffer, layout) - getPageHeight(widget);
        boolean handled = false;
        for (;;) {
            final int previousSelectionEnd = Selection.getSelectionEnd(buffer);
            if (selecting) {
                Selection.extendUp(buffer, layout);
            } else {
                Selection.moveUp(buffer, layout);
            }
            if (Selection.getSelectionEnd(buffer) == previousSelectionEnd) {
                break;
            }
            handled = true;
            if (getCurrentLineTop(buffer, layout) <= targetY) {
                break;
            }
        }
        return handled;
    
protected booleanright(android.widget.TextView widget, android.text.Spannable buffer)

        final Layout layout = widget.getLayout();
        if (isSelecting(buffer)) {
            return Selection.extendRight(buffer, layout);
        } else {
            return Selection.moveRight(buffer, layout);
        }
    
protected booleanrightWord(android.widget.TextView widget, android.text.Spannable buffer)
{@hide}

        final int selectionEnd = widget.getSelectionEnd();
        final WordIterator wordIterator = widget.getWordIterator();
        wordIterator.setCharSequence(buffer, selectionEnd, selectionEnd);
        return Selection.moveToFollowing(buffer, wordIterator, isSelecting(buffer));
    
protected booleantop(android.widget.TextView widget, android.text.Spannable buffer)

        if (isSelecting(buffer)) {
            Selection.extendSelection(buffer, 0);
        } else {
            Selection.setSelection(buffer, 0);
        }
        return true;
    
protected booleanup(android.widget.TextView widget, android.text.Spannable buffer)

        final Layout layout = widget.getLayout();
        if (isSelecting(buffer)) {
            return Selection.extendUp(buffer, layout);
        } else {
            return Selection.moveUp(buffer, layout);
        }