List of usage examples for android.text Editable getSpanEnd
public int getSpanEnd(Object tag);
From source file:android.support.text.emoji.EmojiProcessor.java
private static boolean delete(final Editable content, final KeyEvent event, final boolean forwardDelete) { if (hasModifiers(event)) { return false; }/* w ww .j a v a 2s . co m*/ final int start = Selection.getSelectionStart(content); final int end = Selection.getSelectionEnd(content); if (hasInvalidSelection(start, end)) { return false; } final EmojiSpan[] spans = content.getSpans(start, end, EmojiSpan.class); if (spans != null && spans.length > 0) { final int length = spans.length; for (int index = 0; index < length; index++) { final EmojiSpan span = spans[index]; final int spanStart = content.getSpanStart(span); final int spanEnd = content.getSpanEnd(span); if ((forwardDelete && spanStart == start) || (!forwardDelete && spanEnd == start) || (start > spanStart && start < spanEnd)) { content.delete(spanStart, spanEnd); return true; } } } return false; }
From source file:tv.acfun.a63.CommentsActivity.java
int getQuoteSpanLength(Editable text) { Quote quote = TextViewUtils.getLast(text, Quote.class); int start = text.getSpanStart(quote); int end = text.getSpanEnd(quote); if (start >= 0) { return end - start; }//from w ww.j ava2 s.co m return 0; }
From source file:tv.acfun.a63.CommentsActivity.java
void removeQuote(Editable text) { Quote quote = TextViewUtils.getLast(text, Quote.class); int start = text.getSpanStart(quote); int end = text.getSpanEnd(quote); // Log.d(TAG, String.format("start=%d, end=%d", start, end)); if (start >= 0) { // Log.d(TAG, text.subSequence(start, end).toString()); text.delete(start, end);//from w w w . j a v a2 s . co m } }
From source file:tv.acfun.a63.CommentsActivity.java
String getComment() { Editable text = SpannableStringBuilder.valueOf(mCommentText.getText()); Quote quote = TextViewUtils.getLast(text, Quote.class); int start = text.getSpanStart(quote); int end = text.getSpanEnd(quote); if (start < 0) return text.toString(); else if (start == 0) { return text.subSequence(end, text.length()).toString(); } else/*from w w w. j a va 2 s .co m*/ return text.subSequence(0, start).toString() + text.subSequence(end, text.length()).toString(); }
From source file:com.taobao.weex.dom.WXTextDomObject.java
/** * Truncate the source span to the specified lines. * Caller of this method must ensure that the lines of text is <strong>greater than desired lines and need truncate</strong>. * Otherwise, unexpected behavior may happen. * @param source The source span./*ww w . j a v a 2s . com*/ * @param paint the textPaint * @param desired specified lines. * @param truncateAt truncate method, null value means clipping overflow text directly, non-null value means using ellipsis strategy to clip * @return The spans after clipped. */ private @NonNull Spanned truncate(@Nullable Editable source, @NonNull TextPaint paint, int desired, @Nullable TextUtils.TruncateAt truncateAt) { Spanned ret = new SpannedString(""); if (!TextUtils.isEmpty(source) && source.length() > 0) { if (truncateAt != null) { source.append(ELLIPSIS); Object[] spans = source.getSpans(0, source.length(), Object.class); for (Object span : spans) { int start = source.getSpanStart(span); int end = source.getSpanEnd(span); if (start == 0 && end == source.length() - 1) { source.removeSpan(span); source.setSpan(span, 0, source.length(), source.getSpanFlags(span)); } } } StaticLayout layout; int startOffset; while (source.length() > 1) { startOffset = source.length() - 1; if (truncateAt != null) { startOffset -= 1; } source.delete(startOffset, startOffset + 1); layout = new StaticLayout(source, paint, desired, Layout.Alignment.ALIGN_NORMAL, 1, 0, false); if (layout.getLineCount() <= 1) { ret = source; break; } } } return ret; }
From source file:com.fa.mastodon.activity.ComposeActivity.java
private void removeMediaFromQueue(QueuedMedia item) { mediaPreviewBar.removeView(item.preview); mediaQueued.remove(item);//from ww w .ja va 2s. co m if (mediaQueued.size() == 0) { showMarkSensitive(false); /* If there are no image previews to show, the extra padding that was added to the * EditText can be removed so there isn't unnecessary empty space. */ textEditor.setPadding(textEditor.getPaddingLeft(), textEditor.getPaddingTop(), textEditor.getPaddingRight(), 0); } // Remove the text URL associated with this media. if (item.uploadUrl != null) { Editable text = textEditor.getText(); int start = text.getSpanStart(item.uploadUrl); int end = text.getSpanEnd(item.uploadUrl); if (start != -1 && end != -1) { text.delete(start, end); } } enableMediaButtons(); cancelReadyingMedia(item); }
From source file:android.support.text.emoji.EmojiProcessor.java
/** * Handles deleteSurroundingText commands from {@link InputConnection} and tries to delete an * {@link EmojiSpan} from an {@link Editable}. Returns {@code true} if an {@link EmojiSpan} is * deleted./*from w w w. jav a 2 s. c om*/ * <p/> * If there is a selection where selection start is not equal to selection end, does not * delete. * * @param inputConnection InputConnection instance * @param editable TextView.Editable instance * @param beforeLength the number of characters before the cursor to be deleted * @param afterLength the number of characters after the cursor to be deleted * @param inCodePoints {@code true} if length parameters are in codepoints * * @return {@code true} if an {@link EmojiSpan} is deleted */ static boolean handleDeleteSurroundingText(@NonNull final InputConnection inputConnection, @NonNull final Editable editable, @IntRange(from = 0) final int beforeLength, @IntRange(from = 0) final int afterLength, final boolean inCodePoints) { //noinspection ConstantConditions if (editable == null || inputConnection == null) { return false; } if (beforeLength < 0 || afterLength < 0) { return false; } final int selectionStart = Selection.getSelectionStart(editable); final int selectionEnd = Selection.getSelectionEnd(editable); if (hasInvalidSelection(selectionStart, selectionEnd)) { return false; } int start; int end; if (inCodePoints) { // go backwards in terms of codepoints start = CodepointIndexFinder.findIndexBackward(editable, selectionStart, Math.max(beforeLength, 0)); end = CodepointIndexFinder.findIndexForward(editable, selectionEnd, Math.max(afterLength, 0)); if (start == CodepointIndexFinder.INVALID_INDEX || end == CodepointIndexFinder.INVALID_INDEX) { return false; } } else { start = Math.max(selectionStart - beforeLength, 0); end = Math.min(selectionEnd + afterLength, editable.length()); } final EmojiSpan[] spans = editable.getSpans(start, end, EmojiSpan.class); if (spans != null && spans.length > 0) { final int length = spans.length; for (int index = 0; index < length; index++) { final EmojiSpan span = spans[index]; int spanStart = editable.getSpanStart(span); int spanEnd = editable.getSpanEnd(span); start = Math.min(spanStart, start); end = Math.max(spanEnd, end); } start = Math.max(start, 0); end = Math.min(end, editable.length()); inputConnection.beginBatchEdit(); editable.delete(start, end); inputConnection.endBatchEdit(); return true; } return false; }
From source file:org.zywx.wbpalmstar.plugin.chatkeyboard.ACEChatKeyboardView.java
private void jsonSendDataJsonCallback() { // TODO send callback Json if (mUexBaseObj != null) { JSONObject jsonObject = new JSONObject(); try {//from ww w. j a va2 s. c o m Editable editable = mEditText.getText(); jsonObject.put(EChatKeyboardUtils.CHATKEYBOARD_PARAMS_JSON_KEY_EMOJICONS_TEXT, editable.toString()); JSONArray array = new JSONArray(); ForegroundColorSpan[] spans = editable.getSpans(0, editable.length(), ForegroundColorSpan.class); for (ForegroundColorSpan span : spans) { JSONObject insertObj = new JSONObject(); int spanStart = editable.getSpanStart(span); int spanEnd = editable.getSpanEnd(span); String insertText = editable.subSequence(spanStart, spanEnd).toString(); String insertTextColor = "#" + Integer.toHexString(span.getForegroundColor()).substring(2); insertObj.put(EChatKeyboardUtils.CHATKEYBOARD_PARAMS_JSON_KEY_START, spanStart); insertObj.put(EChatKeyboardUtils.CHATKEYBOARD_PARAMS_JSON_KEY_END, spanEnd); insertObj.put(EChatKeyboardUtils.CHATKEYBOARD_PARAMS_JSON_KEY_INSERTTEXT, insertText); insertObj.put(EChatKeyboardUtils.CHATKEYBOARD_PARAMS_JSON_KEY_INSERTTEXTCOLOR, insertTextColor); array.put(insertObj); } jsonObject.put(EChatKeyboardUtils.CHATKEYBOARD_PARAMS_JSON_KEY_INSERTTEXTS, array); String js = EUExChatKeyboard.SCRIPT_HEADER + "if(" + EChatKeyboardUtils.CHATKEYBOARD_FUN_ON_COMMIT_JSON + "){" + EChatKeyboardUtils.CHATKEYBOARD_FUN_ON_COMMIT_JSON + "(" + jsonObject.toString() + ");}"; mUexBaseObj.onCallback(js); } catch (Exception e) { e.printStackTrace(); } } }
From source file:org.mozilla.focus.widget.InlineAutocompleteEditText.java
/** * Add autocomplete text based on the result URI. * * @param result Result URI to be turned into autocomplete text *///from www. ja va2 s . com public final void onAutocomplete(final String result) { // If mDiscardAutoCompleteResult is true, we temporarily disabled // autocomplete (due to backspacing, etc.) and we should bail early. if (mDiscardAutoCompleteResult) { return; } if (!isEnabled() || result == null) { mAutoCompleteResult = ""; return; } final Editable text = getText(); final int textLength = text.length(); final int resultLength = result.length(); final int autoCompleteStart = text.getSpanStart(AUTOCOMPLETE_SPAN); mAutoCompleteResult = result; if (autoCompleteStart > -1) { // Autocomplete text already exists; we should replace existing autocomplete text. // If the result and the current text don't have the same prefixes, // the result is stale and we should wait for the another result to come in. if (!TextUtils.regionMatches(result, 0, text, 0, autoCompleteStart)) { return; } beginSettingAutocomplete(); // Replace the existing autocomplete text with new one. // replace() preserves the autocomplete spans that we set before. text.replace(autoCompleteStart, textLength, result, autoCompleteStart, resultLength); // Reshow the cursor if there is no longer any autocomplete text. if (autoCompleteStart == resultLength) { setCursorVisible(true); } endSettingAutocomplete(); } else { // No autocomplete text yet; we should add autocomplete text // If the result prefix doesn't match the current text, // the result is stale and we should wait for the another result to come in. if (resultLength <= textLength || !TextUtils.regionMatches(result, 0, text, 0, textLength)) { return; } final Object[] spans = text.getSpans(textLength, textLength, Object.class); final int[] spanStarts = new int[spans.length]; final int[] spanEnds = new int[spans.length]; final int[] spanFlags = new int[spans.length]; // Save selection/composing span bounds so we can restore them later. for (int i = 0; i < spans.length; i++) { final Object span = spans[i]; final int spanFlag = text.getSpanFlags(span); // We don't care about spans that are not selection or composing spans. // For those spans, spanFlag[i] will be 0 and we don't restore them. if ((spanFlag & Spanned.SPAN_COMPOSING) == 0 && (span != Selection.SELECTION_START) && (span != Selection.SELECTION_END)) { continue; } spanStarts[i] = text.getSpanStart(span); spanEnds[i] = text.getSpanEnd(span); spanFlags[i] = spanFlag; } beginSettingAutocomplete(); // First add trailing text. text.append(result, textLength, resultLength); // Restore selection/composing spans. for (int i = 0; i < spans.length; i++) { final int spanFlag = spanFlags[i]; if (spanFlag == 0) { // Skip if the span was ignored before. continue; } text.setSpan(spans[i], spanStarts[i], spanEnds[i], spanFlag); } // Mark added text as autocomplete text. for (final Object span : mAutoCompleteSpans) { text.setSpan(span, textLength, resultLength, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } // Hide the cursor. setCursorVisible(false); // Make sure the autocomplete text is visible. If the autocomplete text is too // long, it would appear the cursor will be scrolled out of view. However, this // is not the case in practice, because EditText still makes sure the cursor is // still in view. bringPointIntoView(resultLength); endSettingAutocomplete(); } announceForAccessibility(text.toString()); }