Loading core/api/current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -45247,6 +45247,8 @@ package android.text { method public static boolean extendRight(android.text.Spannable, android.text.Layout); method public static final void extendSelection(android.text.Spannable, int); method public static boolean extendToLeftEdge(android.text.Spannable, android.text.Layout); method public static boolean extendToParagraphEnd(@NonNull android.text.Spannable); method public static boolean extendToParagraphStart(@NonNull android.text.Spannable); method public static boolean extendToRightEdge(android.text.Spannable, android.text.Layout); method public static boolean extendUp(android.text.Spannable, android.text.Layout); method public static final int getSelectionEnd(CharSequence); Loading @@ -45255,6 +45257,8 @@ package android.text { method public static boolean moveLeft(android.text.Spannable, android.text.Layout); method public static boolean moveRight(android.text.Spannable, android.text.Layout); method public static boolean moveToLeftEdge(android.text.Spannable, android.text.Layout); method public static boolean moveToParagraphEnd(@NonNull android.text.Spannable, @NonNull android.text.Layout); method public static boolean moveToParagraphStart(@NonNull android.text.Spannable, @NonNull android.text.Layout); method public static boolean moveToRightEdge(android.text.Spannable, android.text.Layout); method public static boolean moveUp(android.text.Spannable, android.text.Layout); method public static final void removeSelection(android.text.Spannable); Loading Loading @@ -45703,6 +45707,7 @@ package android.text.method { method protected boolean left(android.widget.TextView, android.text.Spannable); method protected boolean lineEnd(android.widget.TextView, android.text.Spannable); method protected boolean lineStart(android.widget.TextView, android.text.Spannable); method public boolean nextParagraph(@NonNull android.widget.TextView, @NonNull android.text.Spannable); method public boolean onGenericMotionEvent(android.widget.TextView, android.text.Spannable, android.view.MotionEvent); method public boolean onKeyDown(android.widget.TextView, android.text.Spannable, int, android.view.KeyEvent); method public boolean onKeyOther(android.widget.TextView, android.text.Spannable, android.view.KeyEvent); Loading @@ -45712,6 +45717,7 @@ package android.text.method { method public boolean onTrackballEvent(android.widget.TextView, android.text.Spannable, android.view.MotionEvent); method protected boolean pageDown(android.widget.TextView, android.text.Spannable); method protected boolean pageUp(android.widget.TextView, android.text.Spannable); method public boolean previousParagraph(@NonNull android.widget.TextView, @NonNull android.text.Spannable); method protected boolean right(android.widget.TextView, android.text.Spannable); method protected boolean top(android.widget.TextView, android.text.Spannable); method protected boolean up(android.widget.TextView, android.text.Spannable); core/java/android/text/Selection.java +95 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.text; import android.annotation.NonNull; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; Loading Loading @@ -346,6 +347,100 @@ public class Selection { return false; } private static final char PARAGRAPH_SEPARATOR = '\n'; /** * Move the cusrot to the closest paragraph start offset. * * @param text the spannable text * @param layout layout to be used for drawing. * @return true if the cursor is moved, otherwise false. */ public static boolean moveToParagraphStart(@NonNull Spannable text, @NonNull Layout layout) { int start = getSelectionStart(text); int end = getSelectionEnd(text); if (start != end) { setSelection(text, chooseHorizontal(layout, -1, start, end)); return true; } else { int to = TextUtils.lastIndexOf(text, PARAGRAPH_SEPARATOR, start - 1); if (to == -1) { to = 0; // If not found, use the document start offset as a paragraph start. } if (to != end) { setSelection(text, to); return true; } } return false; } /** * Move the cursor to the closest paragraph end offset. * * @param text the spannable text * @param layout layout to be used for drawing. * @return true if the cursor is moved, otherwise false. */ public static boolean moveToParagraphEnd(@NonNull Spannable text, @NonNull Layout layout) { int start = getSelectionStart(text); int end = getSelectionEnd(text); if (start != end) { setSelection(text, chooseHorizontal(layout, 1, start, end)); return true; } else { int to = TextUtils.indexOf(text, PARAGRAPH_SEPARATOR, end + 1); if (to == -1) { to = text.length(); } if (to != end) { setSelection(text, to); return true; } } return false; } /** * Extend the selection to the closest paragraph start offset. * * @param text the spannable text * @return true if the selection is extended, otherwise false */ public static boolean extendToParagraphStart(@NonNull Spannable text) { int end = getSelectionEnd(text); int to = TextUtils.lastIndexOf(text, PARAGRAPH_SEPARATOR, end - 1); if (to == -1) { to = 0; // If not found, use the document start offset as a paragraph start. } if (to != end) { extendSelection(text, to); return true; } return false; } /** * Extend the selection to the closest paragraph end offset. * * @param text the spannable text * @return true if the selection is extended, otherwise false */ public static boolean extendToParagraphEnd(@NonNull Spannable text) { int end = getSelectionEnd(text); int to = TextUtils.indexOf(text, PARAGRAPH_SEPARATOR, end + 1); if (to == -1) { to = text.length(); } if (to != end) { extendSelection(text, to); return true; } return false; } /** * Move the selection end to the buffer offset physically above * the current selection end. Loading core/java/android/text/method/ArrowKeyMovementMethod.java +21 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.text.method; import android.annotation.NonNull; import android.graphics.Rect; import android.text.Layout; import android.text.Selection; Loading Loading @@ -221,6 +222,26 @@ public class ArrowKeyMovementMethod extends BaseMovementMethod implements Moveme return lineEnd(widget, buffer); } @Override public boolean previousParagraph(@NonNull TextView widget, @NonNull Spannable buffer) { final Layout layout = widget.getLayout(); if (isSelecting(buffer)) { return Selection.extendToParagraphStart(buffer); } else { return Selection.moveToParagraphStart(buffer, layout); } } @Override public boolean nextParagraph(@NonNull TextView widget, @NonNull Spannable buffer) { final Layout layout = widget.getLayout(); if (isSelecting(buffer)) { return Selection.extendToParagraphEnd(buffer); } else { return Selection.moveToParagraphEnd(buffer, layout); } } @Override public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { int initialScrollX = -1; Loading core/java/android/text/method/BaseMovementMethod.java +29 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.text.method; import android.annotation.NonNull; import android.text.Layout; import android.text.Spannable; import android.view.InputDevice; Loading Loading @@ -190,6 +191,9 @@ public class BaseMovementMethod implements MovementMethod { } else if (KeyEvent.metaStateHasModifiers(movementMetaState, KeyEvent.META_ALT_ON)) { return top(widget, buffer); } else if (KeyEvent.metaStateHasModifiers(movementMetaState, KeyEvent.META_CTRL_ON)) { return previousParagraph(widget, buffer); } break; Loading @@ -199,6 +203,9 @@ public class BaseMovementMethod implements MovementMethod { } else if (KeyEvent.metaStateHasModifiers(movementMetaState, KeyEvent.META_ALT_ON)) { return bottom(widget, buffer); } else if (KeyEvent.metaStateHasModifiers(movementMetaState, KeyEvent.META_CTRL_ON)) { return nextParagraph(widget, buffer); } break; Loading Loading @@ -399,6 +406,28 @@ public class BaseMovementMethod implements MovementMethod { return false; } /** * Performs a previous paragraph movement action. * * @param widget the text view * @param buffer the text buffer * @return true if the event was handled, otherwise false. */ public boolean previousParagraph(@NonNull TextView widget, @NonNull Spannable buffer) { return false; } /** * Performs a next paragraph movement action. * * @param widget the text view * @param buffer the text buffer * @return true if the event was handled, otherwise false. */ public boolean nextParagraph(@NonNull TextView widget, @NonNull Spannable buffer) { return false; } private int getTopLine(TextView widget) { return widget.getLayout().getLineForVertical(widget.getScrollY()); } Loading Loading
core/api/current.txt +6 −0 Original line number Diff line number Diff line Loading @@ -45247,6 +45247,8 @@ package android.text { method public static boolean extendRight(android.text.Spannable, android.text.Layout); method public static final void extendSelection(android.text.Spannable, int); method public static boolean extendToLeftEdge(android.text.Spannable, android.text.Layout); method public static boolean extendToParagraphEnd(@NonNull android.text.Spannable); method public static boolean extendToParagraphStart(@NonNull android.text.Spannable); method public static boolean extendToRightEdge(android.text.Spannable, android.text.Layout); method public static boolean extendUp(android.text.Spannable, android.text.Layout); method public static final int getSelectionEnd(CharSequence); Loading @@ -45255,6 +45257,8 @@ package android.text { method public static boolean moveLeft(android.text.Spannable, android.text.Layout); method public static boolean moveRight(android.text.Spannable, android.text.Layout); method public static boolean moveToLeftEdge(android.text.Spannable, android.text.Layout); method public static boolean moveToParagraphEnd(@NonNull android.text.Spannable, @NonNull android.text.Layout); method public static boolean moveToParagraphStart(@NonNull android.text.Spannable, @NonNull android.text.Layout); method public static boolean moveToRightEdge(android.text.Spannable, android.text.Layout); method public static boolean moveUp(android.text.Spannable, android.text.Layout); method public static final void removeSelection(android.text.Spannable); Loading Loading @@ -45703,6 +45707,7 @@ package android.text.method { method protected boolean left(android.widget.TextView, android.text.Spannable); method protected boolean lineEnd(android.widget.TextView, android.text.Spannable); method protected boolean lineStart(android.widget.TextView, android.text.Spannable); method public boolean nextParagraph(@NonNull android.widget.TextView, @NonNull android.text.Spannable); method public boolean onGenericMotionEvent(android.widget.TextView, android.text.Spannable, android.view.MotionEvent); method public boolean onKeyDown(android.widget.TextView, android.text.Spannable, int, android.view.KeyEvent); method public boolean onKeyOther(android.widget.TextView, android.text.Spannable, android.view.KeyEvent); Loading @@ -45712,6 +45717,7 @@ package android.text.method { method public boolean onTrackballEvent(android.widget.TextView, android.text.Spannable, android.view.MotionEvent); method protected boolean pageDown(android.widget.TextView, android.text.Spannable); method protected boolean pageUp(android.widget.TextView, android.text.Spannable); method public boolean previousParagraph(@NonNull android.widget.TextView, @NonNull android.text.Spannable); method protected boolean right(android.widget.TextView, android.text.Spannable); method protected boolean top(android.widget.TextView, android.text.Spannable); method protected boolean up(android.widget.TextView, android.text.Spannable);
core/java/android/text/Selection.java +95 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.text; import android.annotation.NonNull; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; Loading Loading @@ -346,6 +347,100 @@ public class Selection { return false; } private static final char PARAGRAPH_SEPARATOR = '\n'; /** * Move the cusrot to the closest paragraph start offset. * * @param text the spannable text * @param layout layout to be used for drawing. * @return true if the cursor is moved, otherwise false. */ public static boolean moveToParagraphStart(@NonNull Spannable text, @NonNull Layout layout) { int start = getSelectionStart(text); int end = getSelectionEnd(text); if (start != end) { setSelection(text, chooseHorizontal(layout, -1, start, end)); return true; } else { int to = TextUtils.lastIndexOf(text, PARAGRAPH_SEPARATOR, start - 1); if (to == -1) { to = 0; // If not found, use the document start offset as a paragraph start. } if (to != end) { setSelection(text, to); return true; } } return false; } /** * Move the cursor to the closest paragraph end offset. * * @param text the spannable text * @param layout layout to be used for drawing. * @return true if the cursor is moved, otherwise false. */ public static boolean moveToParagraphEnd(@NonNull Spannable text, @NonNull Layout layout) { int start = getSelectionStart(text); int end = getSelectionEnd(text); if (start != end) { setSelection(text, chooseHorizontal(layout, 1, start, end)); return true; } else { int to = TextUtils.indexOf(text, PARAGRAPH_SEPARATOR, end + 1); if (to == -1) { to = text.length(); } if (to != end) { setSelection(text, to); return true; } } return false; } /** * Extend the selection to the closest paragraph start offset. * * @param text the spannable text * @return true if the selection is extended, otherwise false */ public static boolean extendToParagraphStart(@NonNull Spannable text) { int end = getSelectionEnd(text); int to = TextUtils.lastIndexOf(text, PARAGRAPH_SEPARATOR, end - 1); if (to == -1) { to = 0; // If not found, use the document start offset as a paragraph start. } if (to != end) { extendSelection(text, to); return true; } return false; } /** * Extend the selection to the closest paragraph end offset. * * @param text the spannable text * @return true if the selection is extended, otherwise false */ public static boolean extendToParagraphEnd(@NonNull Spannable text) { int end = getSelectionEnd(text); int to = TextUtils.indexOf(text, PARAGRAPH_SEPARATOR, end + 1); if (to == -1) { to = text.length(); } if (to != end) { extendSelection(text, to); return true; } return false; } /** * Move the selection end to the buffer offset physically above * the current selection end. Loading
core/java/android/text/method/ArrowKeyMovementMethod.java +21 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.text.method; import android.annotation.NonNull; import android.graphics.Rect; import android.text.Layout; import android.text.Selection; Loading Loading @@ -221,6 +222,26 @@ public class ArrowKeyMovementMethod extends BaseMovementMethod implements Moveme return lineEnd(widget, buffer); } @Override public boolean previousParagraph(@NonNull TextView widget, @NonNull Spannable buffer) { final Layout layout = widget.getLayout(); if (isSelecting(buffer)) { return Selection.extendToParagraphStart(buffer); } else { return Selection.moveToParagraphStart(buffer, layout); } } @Override public boolean nextParagraph(@NonNull TextView widget, @NonNull Spannable buffer) { final Layout layout = widget.getLayout(); if (isSelecting(buffer)) { return Selection.extendToParagraphEnd(buffer); } else { return Selection.moveToParagraphEnd(buffer, layout); } } @Override public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { int initialScrollX = -1; Loading
core/java/android/text/method/BaseMovementMethod.java +29 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.text.method; import android.annotation.NonNull; import android.text.Layout; import android.text.Spannable; import android.view.InputDevice; Loading Loading @@ -190,6 +191,9 @@ public class BaseMovementMethod implements MovementMethod { } else if (KeyEvent.metaStateHasModifiers(movementMetaState, KeyEvent.META_ALT_ON)) { return top(widget, buffer); } else if (KeyEvent.metaStateHasModifiers(movementMetaState, KeyEvent.META_CTRL_ON)) { return previousParagraph(widget, buffer); } break; Loading @@ -199,6 +203,9 @@ public class BaseMovementMethod implements MovementMethod { } else if (KeyEvent.metaStateHasModifiers(movementMetaState, KeyEvent.META_ALT_ON)) { return bottom(widget, buffer); } else if (KeyEvent.metaStateHasModifiers(movementMetaState, KeyEvent.META_CTRL_ON)) { return nextParagraph(widget, buffer); } break; Loading Loading @@ -399,6 +406,28 @@ public class BaseMovementMethod implements MovementMethod { return false; } /** * Performs a previous paragraph movement action. * * @param widget the text view * @param buffer the text buffer * @return true if the event was handled, otherwise false. */ public boolean previousParagraph(@NonNull TextView widget, @NonNull Spannable buffer) { return false; } /** * Performs a next paragraph movement action. * * @param widget the text view * @param buffer the text buffer * @return true if the event was handled, otherwise false. */ public boolean nextParagraph(@NonNull TextView widget, @NonNull Spannable buffer) { return false; } private int getTopLine(TextView widget) { return widget.getLayout().getLineForVertical(widget.getScrollY()); } Loading