下面列出了android.text.Selection#getSelectionStart ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public void format(final Editable to, final int toStart, final int toEnd, final CharSequence from,
final int fromStart, final int fromEnd) {
final int selectionStart = Selection.getSelectionStart(to);
final int selectionEnd = Selection.getSelectionStart(to);
buffer.clear();
buffer.append(to);
if (selectionStart != -1 && selectionEnd != -1) {
Selection.setSelection(buffer, selectionStart, selectionEnd);
}
buffer.replace(toStart, toEnd, from, fromStart, fromEnd);
if (!TextUtils.isGraphic(buffer)) {
return;
}
formatPhoneNumberInput(buffer);
}
public void run() {
Spannable buf = mBuffer;
if (buf != null) {
int st = Selection.getSelectionStart(buf);
int en = Selection.getSelectionEnd(buf);
int start = buf.getSpanStart(TextKeyListener.ACTIVE);
int end = buf.getSpanEnd(TextKeyListener.ACTIVE);
if (st == start && en == end) {
Selection.setSelection(buf, Selection.getSelectionEnd(buf));
}
buf.removeSpan(Timeout.this);
}
}
public void onBeforeNotifyDataSetChanged() {
if (SUPPORTED) {
HANDLER.removeMessages(MESSAGE_SEND_RESET);
HANDLER.removeMessages(MESSAGE_RESET);
HANDLER.removeMessages(MESSAGE_START_SELECTION);
if (selectionActionMode != null) {
final CharSequence text = selectionTextView.getText();
futureSelectionIdentifier = selectionIdentifier;
futureSelectionStart = Selection.getSelectionStart(text);
futureSelectionEnd = Selection.getSelectionEnd(text);
selectionActionMode.finish();
selectionActionMode = null;
selectionIdentifier = null;
selectionTextView = null;
}
}
}
private void formatPhoneNumberInput(final Editable input) {
final int selection = Selection.getSelectionStart(buffer);
boolean selectionPositionRemembered = false;
asYouTypeFormatter.clear();
String phoneNumberText = "";
int offset = 0;
final int length = input.length();
while (offset < length) {
final int codePoint = Character.codePointAt(input, offset);
if (Character.isDigit(codePoint)) {
final char digit = CodePoint.toDigitChar(codePoint);
selectionPositionRemembered = selectionPositionRemembered || offset >= selection;
phoneNumberText = asYouTypeFormatter.inputDigit(digit, !selectionPositionRemembered);
}
offset += Character.charCount(codePoint);
}
input.replace(0, input.length(), phoneNumberText);
if (selection != -1) {
Selection.setSelection(input,
selectionPositionRemembered ? asYouTypeFormatter.getRememberedPosition() : phoneNumberText.length());
}
}
/**
* The default implementation returns the given amount of text from the
* current cursor position in the buffer.
*/
public CharSequence getTextBeforeCursor(int length, int flags) {
final Editable content = getEditable();
if (content == null) return null;
int a = Selection.getSelectionStart(content);
int b = Selection.getSelectionEnd(content);
if (a > b) {
int tmp = a;
a = b;
b = tmp;
}
if (a <= 0) {
return "";
}
if (length > a) {
length = a;
}
if ((flags&GET_TEXT_WITH_STYLES) != 0) {
return content.subSequence(a - length, a);
}
return TextUtils.substring(content, a - length, a);
}
/**
* Performs the action that happens when you press the DEL key in
* a TextView. If there is a selection, deletes the selection;
* otherwise, DEL alone deletes the character before the cursor,
* if any;
* ALT+DEL deletes everything on the line the cursor is on.
*
* @return true if anything was deleted; false otherwise.
*/
public boolean forwardDelete(View view, Editable content, int keyCode,
KeyEvent event) {
int selStart, selEnd;
boolean result = true;
{
int a = Selection.getSelectionStart(content);
int b = Selection.getSelectionEnd(content);
selStart = Math.min(a, b);
selEnd = Math.max(a, b);
}
if (selStart != selEnd) {
content.delete(selStart, selEnd);
} else {
int to = TextUtils.getOffsetAfter(content, selEnd);
if (to != selEnd) {
content.delete(Math.min(to, selEnd), Math.max(to, selEnd));
}
else {
result = false;
}
}
if (result)
adjustMetaAfterKeypress(content);
return result;
}
/**
* The default implementation returns the given amount of text from the
* current cursor position in the buffer.
*/
public CharSequence getTextAfterCursor(int length, int flags) {
final Editable content = getEditable();
if (content == null) return null;
int a = Selection.getSelectionStart(content);
int b = Selection.getSelectionEnd(content);
if (a > b) {
int tmp = a;
a = b;
b = tmp;
}
// Guard against the case where the cursor has not been positioned yet.
if (b < 0) {
b = 0;
}
if (b + length > content.length()) {
length = content.length() - b;
}
if ((flags&GET_TEXT_WITH_STYLES) != 0) {
return content.subSequence(b, b + length);
}
return TextUtils.substring(content, b, b + length);
}
/**
* @see BaseInputConnection#getExtractedText(android.view.inputmethod.ExtractedTextRequest,
* int)
*/
@Override
public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) {
if (DEBUG) Log.w(TAG, "getExtractedText");
ExtractedText et = new ExtractedText();
Editable editable = getEditable();
et.text = editable.toString();
et.partialEndOffset = editable.length();
et.selectionStart = Selection.getSelectionStart(editable);
et.selectionEnd = Selection.getSelectionEnd(editable);
et.flags = mSingleLine ? ExtractedText.FLAG_SINGLE_LINE : 0;
return et;
}
private boolean deleteSelection(View view, Editable content) {
int selectionStart = Selection.getSelectionStart(content);
int selectionEnd = Selection.getSelectionEnd(content);
if (selectionEnd < selectionStart) {
int temp = selectionEnd;
selectionEnd = selectionStart;
selectionStart = temp;
}
if (selectionStart != selectionEnd) {
content.delete(selectionStart, selectionEnd);
return true;
}
return false;
}
@VisibleForTesting
ImeState getImeStateForTesting() {
Editable editable = getEditable();
String text = editable.toString();
int selectionStart = Selection.getSelectionStart(editable);
int selectionEnd = Selection.getSelectionEnd(editable);
int compositionStart = getComposingSpanStart(editable);
int compositionEnd = getComposingSpanEnd(editable);
return new ImeState(text, selectionStart, selectionEnd, compositionStart, compositionEnd);
}
@VisibleForTesting
ImeState getImeStateForTesting() {
Editable editable = getEditable();
String text = editable.toString();
int selectionStart = Selection.getSelectionStart(editable);
int selectionEnd = Selection.getSelectionEnd(editable);
int compositionStart = getComposingSpanStart(editable);
int compositionEnd = getComposingSpanEnd(editable);
return new ImeState(text, selectionStart, selectionEnd, compositionStart, compositionEnd);
}
@Override
public boolean onKeyDown(View view, Editable content, int keyCode, KeyEvent event) {
boolean result = super.onKeyDown(view, content, keyCode, event);
// auto indent
if ( sAutoIndent && keyCode == KeyEvent.KEYCODE_ENTER ){
int a = Selection.getSelectionStart(content);
int b = Selection.getSelectionEnd(content);
if ( a == b ){
// search head of previous line
int prev = a-2;
while( prev >=0 && content.charAt(prev)!='\n' ){
prev--;
}
prev ++;
int pos = prev;
while( content.charAt(pos)==' ' || content.charAt(pos)=='\t' || content.charAt(pos)=='\u3000'){
pos++;
}
int len = pos-prev;
if ( len > 0 ){
char [] dest = new char[len];
content.getChars(prev, pos, dest, 0);
content.replace(a,b, new String(dest) );
Selection.setSelection(content, a+len);
}
}
}
if ( Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB ){
if (keyCode == KEYCODE_FORWARD_DEL ) {
if ( (event.getMetaState() & 512) == 0 ){ // workaround for Galaxy Note
forwardDelete(view, content, keyCode, event);
return true;
}
}
}
return result;
}
/**
* @see BaseInputConnection#sendKeyEvent(android.view.KeyEvent)
*/
@Override
public boolean sendKeyEvent(KeyEvent event) {
if (DEBUG) {
Log.w(TAG, "sendKeyEvent [" + event.getAction() + "] [" + event.getKeyCode() + "]");
}
// If this is a key-up, and backspace/del or if the key has a character representation,
// need to update the underlying Editable (i.e. the local representation of the text
// being edited).
if (event.getAction() == KeyEvent.ACTION_UP) {
if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
deleteSurroundingText(1, 0);
return true;
} else if (event.getKeyCode() == KeyEvent.KEYCODE_FORWARD_DEL) {
deleteSurroundingText(0, 1);
return true;
} else {
int unicodeChar = event.getUnicodeChar();
if (unicodeChar != 0) {
Editable editable = getEditable();
int selectionStart = Selection.getSelectionStart(editable);
int selectionEnd = Selection.getSelectionEnd(editable);
if (selectionStart > selectionEnd) {
int temp = selectionStart;
selectionStart = selectionEnd;
selectionEnd = temp;
}
editable.replace(selectionStart, selectionEnd,
Character.toString((char)unicodeChar));
}
}
} else if (event.getAction() == KeyEvent.ACTION_DOWN) {
// TODO(aurimas): remove this workaround when crbug.com/278584 is fixed.
if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
beginBatchEdit();
finishComposingText();
mImeAdapter.translateAndSendNativeEvents(event);
endBatchEdit();
return true;
} else if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
return true;
} else if (event.getKeyCode() == KeyEvent.KEYCODE_FORWARD_DEL) {
return true;
}
}
mImeAdapter.translateAndSendNativeEvents(event);
return true;
}
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;
}
@Override
public boolean onKeyDown(View view, Editable content, int keyCode, KeyEvent event) {
boolean result = super.onKeyDown(view, content, keyCode, event);
// auto indent
if ( sAutoIndent && keyCode == KeyEvent.KEYCODE_ENTER ){
int a = Selection.getSelectionStart(content);
int b = Selection.getSelectionEnd(content);
if ( a == b ){
// search head of previous line
int prev = a-2;
while( prev >=0 && content.charAt(prev)!='\n' ){
prev--;
}
prev ++;
int pos = prev;
while( content.charAt(pos)==' ' || content.charAt(pos)=='\t' || content.charAt(pos)=='\u3000'){
pos++;
}
int len = pos-prev;
if ( len > 0 ){
char [] dest = new char[len];
content.getChars(prev, pos, dest, 0);
content.replace(a,b, new String(dest) );
Selection.setSelection(content, a+len);
}
}
}
if ( Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB ){
if (keyCode == KEYCODE_FORWARD_DEL ) {
if ( (event.getMetaState() & 512) == 0 ){ // workaround for Galaxy Note
forwardDelete(view, content, keyCode, event);
return true;
}
}
}
return result;
}
public int getSelection() {
return Selection.getSelectionStart(buffer);
}
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;
}
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;
}
@Override
public boolean commitText(CharSequence text, int newCursorPosition) {
Editable currentText = getText();
if (currentText == null) return super.commitText(text, newCursorPosition);
int selectionStart = Selection.getSelectionStart(currentText);
int selectionEnd = Selection.getSelectionEnd(currentText);
int autocompleteIndex = currentText.getSpanStart(mAutocompleteSpan);
// If the text being committed is a single character that matches the next character
// in the selection (assumed to be the autocomplete text), we only move the text
// selection instead clearing the autocomplete text causing flickering as the
// autocomplete text will appear once the next suggestions are received.
//
// To be confident that the selection is an autocomplete, we ensure the selection
// is at least one character and the end of the selection is the end of the
// currently entered text.
if (newCursorPosition == 1 && selectionStart > 0 && selectionStart != selectionEnd
&& selectionEnd >= currentText.length()
&& autocompleteIndex == selectionStart
&& text.length() == 1) {
currentText.getChars(selectionStart, selectionStart + 1, mTempSelectionChar, 0);
if (mTempSelectionChar[0] == text.charAt(0)) {
// Since the text isn't changing, TalkBack won't read out the typed characters.
// To work around this, explicitly send an accessibility event. crbug.com/416595
if (mAccessibilityManager != null && mAccessibilityManager.isEnabled()) {
AccessibilityEvent event = AccessibilityEvent.obtain(
AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
event.setFromIndex(selectionStart);
event.setRemovedCount(0);
event.setAddedCount(1);
event.setBeforeText(currentText.toString().substring(0, selectionStart));
sendAccessibilityEventUnchecked(event);
}
setAutocompleteText(
currentText.subSequence(0, selectionStart + 1),
currentText.subSequence(selectionStart + 1, selectionEnd));
if (!mInBatchEditMode) {
notifyAutocompleteTextStateChanged(false);
}
return true;
}
}
boolean retVal = super.commitText(text, newCursorPosition);
// Ensure the autocomplete span is removed if it is no longer valid after committing the
// text.
if (getText().getSpanStart(mAutocompleteSpan) >= 0) clearAutocompleteSpanIfInvalid();
return retVal;
}
@Override
public boolean commitText(CharSequence text, int newCursorPosition) {
Editable currentText = getText();
if (currentText == null) return super.commitText(text, newCursorPosition);
int selectionStart = Selection.getSelectionStart(currentText);
int selectionEnd = Selection.getSelectionEnd(currentText);
int autocompleteIndex = currentText.getSpanStart(mAutocompleteSpan);
// If the text being committed is a single character that matches the next character
// in the selection (assumed to be the autocomplete text), we only move the text
// selection instead clearing the autocomplete text causing flickering as the
// autocomplete text will appear once the next suggestions are received.
//
// To be confident that the selection is an autocomplete, we ensure the selection
// is at least one character and the end of the selection is the end of the
// currently entered text.
if (newCursorPosition == 1 && selectionStart > 0 && selectionStart != selectionEnd
&& selectionEnd >= currentText.length()
&& autocompleteIndex == selectionStart
&& text.length() == 1) {
currentText.getChars(selectionStart, selectionStart + 1, mTempSelectionChar, 0);
if (mTempSelectionChar[0] == text.charAt(0)) {
// Since the text isn't changing, TalkBack won't read out the typed characters.
// To work around this, explicitly send an accessibility event. crbug.com/416595
if (mAccessibilityManager != null && mAccessibilityManager.isEnabled()) {
AccessibilityEvent event = AccessibilityEvent.obtain(
AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
event.setFromIndex(selectionStart);
event.setRemovedCount(0);
event.setAddedCount(1);
event.setBeforeText(currentText.toString().substring(0, selectionStart));
sendAccessibilityEventUnchecked(event);
}
setAutocompleteText(
currentText.subSequence(0, selectionStart + 1),
currentText.subSequence(selectionStart + 1, selectionEnd));
if (!mInBatchEditMode) {
notifyAutocompleteTextStateChanged(false);
}
return true;
}
}
boolean retVal = super.commitText(text, newCursorPosition);
// Ensure the autocomplete span is removed if it is no longer valid after committing the
// text.
if (getText().getSpanStart(mAutocompleteSpan) >= 0) clearAutocompleteSpanIfInvalid();
return retVal;
}