Java Code Examples for android.text.Editable#getSpanEnd()
The following examples show how to use
android.text.Editable#getSpanEnd() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: AutoCompleteEditText.java From Carbon with Apache License 2.0 | 6 votes |
@Override protected void onSelectionChanged(int selStart, int selEnd) { if (autoCompleting) return; if (selStart == selEnd) { Editable text = getText(); HintSpan[] spans = text.getSpans(0, length(), HintSpan.class); if (spans.length > 1) throw new IllegalStateException("more than one HintSpan"); autoCompleting = true; if (spans.length == 1) { HintSpan span = spans[0]; if (selStart >= text.getSpanStart(span) && selStart < text.getSpanEnd(span)) { setSelection(text.getSpanStart(span)); } else if (selStart == text.getSpanEnd(span)) { text.removeSpan(span); super.setImeOptions(prevOptions); } } } autoComplete(); autoCompleting = false; super.onSelectionChanged(selStart, selEnd); }
Example 2
Source File: TokenCompleteTextView.java From TokenAutoComplete with Apache License 2.0 | 6 votes |
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { // count > 0 means something will be deleted if (count > 0 && getText() != null) { Editable text = getText(); int end = start + count; TokenImageSpan[] spans = text.getSpans(start, end, TokenImageSpan.class); //NOTE: I'm not completely sure this won't cause problems if we get stuck in a text changed loop //but it appears to work fine. Spans will stop getting removed if this breaks. ArrayList<TokenImageSpan> spansToRemove = new ArrayList<>(); for (TokenImageSpan token : spans) { if (text.getSpanStart(token) < end && start < text.getSpanEnd(token)) { spansToRemove.add(token); } } this.spansToRemove = spansToRemove; } }
Example 3
Source File: MentionsEditText.java From Spyglass with Apache License 2.0 | 6 votes |
/** * Temporarily remove MentionSpans that may interfere with composing text. Note that software keyboards are allowed * to place arbitrary spans over the text. This was resulting in several bugs in edge cases while handling the * MentionSpans while composing text (with different issues for different keyboards). The easiest solution for this * is to remove any MentionSpans that could cause issues while the user is changing text. * * Note: The MentionSpans are added again in {@link #replacePlaceholdersWithCorrespondingMentionSpans(Editable)} * * @param text the current text before it changes */ private void replaceMentionSpansWithPlaceholdersAsNecessary(@NonNull CharSequence text) { int index = getSelectionStart(); int wordStart = findStartOfWord(text, index); Editable editable = getText(); MentionSpan[] mentionSpansInCurrentWord = editable.getSpans(wordStart, index, MentionSpan.class); for (MentionSpan span : mentionSpansInCurrentWord) { if (span.getDisplayMode() != Mentionable.MentionDisplayMode.NONE) { int spanStart = editable.getSpanStart(span); int spanEnd = editable.getSpanEnd(span); editable.setSpan(new PlaceholderSpan(span, spanStart, spanEnd), spanStart, spanEnd, Spanned.SPAN_EXCLUSIVE_INCLUSIVE); editable.removeSpan(span); } } }
Example 4
Source File: TokenCompleteTextView.java From TokenAutoComplete with Apache License 2.0 | 6 votes |
/** * Remove a span from the current EditText and fire the appropriate callback * * @param text Editable to remove the span from * @param span TokenImageSpan to be removed */ private void removeSpan(Editable text, TokenImageSpan span) { //We usually add whitespace after a token, so let's try to remove it as well if it's present int end = text.getSpanEnd(span); if (end < text.length() && text.charAt(end) == ' ') { end += 1; } internalEditInProgress = true; text.delete(text.getSpanStart(span), end); internalEditInProgress = false; if (allowCollapse && !isFocused()) { updateCountSpan(); } }
Example 5
Source File: RichEditText.java From o2oa with GNU Affero General Public License v3.0 | 6 votes |
@Override public void afterTextChanged(Editable s) { final TagSpan span = willDelSpan; log("TagSpanTextWatcher#willRemove#span:" + (span == null ? "null" : span.toString())); if (span != null && span.willRemove) { int start = s.getSpanStart(span); int end = s.getSpanEnd(span); // Remove the span s.removeSpan(span); // Remove the remaining emoticon text. if (start != end) { s.delete(start, end); } } }
Example 6
Source File: FixedURLSpan.java From Conversations with GNU General Public License v3.0 | 5 votes |
public static void fix(final Editable editable) { for (final URLSpan urlspan : editable.getSpans(0, editable.length() - 1, URLSpan.class)) { final int start = editable.getSpanStart(urlspan); final int end = editable.getSpanEnd(urlspan); editable.removeSpan(urlspan); editable.setSpan(new FixedURLSpan(urlspan.getURL()), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } }
Example 7
Source File: TokenCompleteTextView.java From TokenAutoComplete with Apache License 2.0 | 5 votes |
/** * Checks if selection can be deleted. This method is called from TokenInputConnection . * @param beforeLength the number of characters before the current selection end to check * @return true if there are no non-deletable pieces of the section */ @SuppressWarnings("BooleanMethodIsAlwaysInverted") public boolean canDeleteSelection(int beforeLength) { if (getObjects().size() < 1) return true; // if beforeLength is 1, we either have no selection or the call is coming from OnKey Event. // In these scenarios, getSelectionStart() will return the correct value. int endSelection = getSelectionEnd(); int startSelection = beforeLength == 1 ? getSelectionStart() : endSelection - beforeLength; Editable text = getText(); TokenImageSpan[] spans = text.getSpans(0, text.length(), TokenImageSpan.class); // Iterate over all tokens and allow the deletion // if there are no tokens not removable in the selection for (TokenImageSpan span : spans) { int startTokenSelection = text.getSpanStart(span); int endTokenSelection = text.getSpanEnd(span); // moving on, no need to check this token if (isTokenRemovable(span.token)) continue; if (startSelection == endSelection) { // Delete single if (endTokenSelection + 1 == endSelection) { return false; } } else { // Delete range // Don't delete if a non removable token is in range if (startSelection <= startTokenSelection && endTokenSelection + 1 <= endSelection) { return false; } } } return true; }
Example 8
Source File: NormalStyle.java From YCCustomText with Apache License 2.0 | 5 votes |
/** * 样式情况判断 * @param editable editable * @param start start * @param end end */ public void applyStyle(Editable editable, int start, int end) { //获取 从 start 到 end 位置上所有的指定 class 类型的 Span数组 E[] spans = editable.getSpans(start, end, clazzE); E existingSpan = null; if (spans.length > 0) { existingSpan = spans[0]; } if (existingSpan == null) { //当前选中内部无此样式,开始设置span样式 checkAndMergeSpan(editable, start, end, clazzE); } else { //获取 一个 span 的起始位置 int existingSpanStart = editable.getSpanStart(existingSpan); //获取一个span 的结束位置 int existingSpanEnd = editable.getSpanEnd(existingSpan); if (existingSpanStart <= start && existingSpanEnd >= end) { //在一个 完整的 span 中 //当我们选中的区域在一段连续的 Bold 样式里面的时候,再次选择Bold将会取消样式 //删除 样式 removeStyle(editable, start, end, clazzE, true); } else { //当前选中区域存在了某某样式,需要合并样式 checkAndMergeSpan(editable, start, end, clazzE); } } }
Example 9
Source File: GroupUsersFragment.java From actor-platform with GNU Affero General Public License v3.0 | 5 votes |
private void checkForDeletions(Editable editable) { Integer[] selected = getSelected(); boolean hasDeletions = false; UserSpan[] spans = editable.getSpans(0, editable.length(), UserSpan.class); for (Integer u : selected) { boolean founded = false; for (UserSpan span : spans) { if (span.getUser().getId() == u) { if (editable.getSpanStart(span) == editable.getSpanEnd(span)) { break; } else { founded = true; break; } } } if (!founded) { hasDeletions = true; unselect(u); } } if (hasDeletions) { getActivity().invalidateOptionsMenu(); getAdapter().notifyDataSetChanged(); } }
Example 10
Source File: MentionsEditText.java From Spyglass with Apache License 2.0 | 5 votes |
/** * Resets the given {@link MentionSpan} in the editor, forcing it to redraw with its latest drawable state. * * @param span the {@link MentionSpan} to update */ public void updateSpan(@NonNull MentionSpan span) { mBlockCompletion = true; Editable text = getText(); int start = text.getSpanStart(span); int end = text.getSpanEnd(span); if (start >= 0 && end > start && end <= text.length()) { text.removeSpan(span); text.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } mBlockCompletion = false; }
Example 11
Source File: EditTextCaption.java From TelePlus-Android with GNU General Public License v2.0 | 5 votes |
private void applyTextStyleToSelection(TypefaceSpan span) { int start; int end; if (selectionStart >= 0 && selectionEnd >= 0) { start = selectionStart; end = selectionEnd; selectionStart = selectionEnd = -1; } else { start = getSelectionStart(); end = getSelectionEnd(); } Editable editable = getText(); CharacterStyle spans[] = editable.getSpans(start, end, CharacterStyle.class); if (spans != null && spans.length > 0) { for (int a = 0; a < spans.length; a++) { CharacterStyle oldSpan = spans[a]; int spanStart = editable.getSpanStart(oldSpan); int spanEnd = editable.getSpanEnd(oldSpan); editable.removeSpan(oldSpan); if (spanStart < start) { editable.setSpan(oldSpan, spanStart, start, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } if (spanEnd > end) { editable.setSpan(oldSpan, end, spanEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } } } if (span != null) { editable.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } if (delegate != null) { delegate.onSpansChanged(); } }
Example 12
Source File: TokenCompleteTextView.java From TokenAutoComplete with Apache License 2.0 | 5 votes |
private Range getCurrentCandidateTokenRange() { Editable editable = getText(); int cursorEndPosition = getSelectionEnd(); int candidateStringStart = prefix.length(); int candidateStringEnd = editable.length(); if (hintVisible) { //Don't try to search the hint for possible tokenizable strings candidateStringEnd = candidateStringStart; } //We want to find the largest string that contains the selection end that is not already tokenized TokenImageSpan[] spans = editable.getSpans(prefix.length(), editable.length(), TokenImageSpan.class); for (TokenImageSpan span : spans) { int spanEnd = editable.getSpanEnd(span); if (candidateStringStart < spanEnd && cursorEndPosition >= spanEnd) { candidateStringStart = spanEnd; } int spanStart = editable.getSpanStart(span); if (candidateStringEnd > spanStart && cursorEndPosition <= spanEnd) { candidateStringEnd = spanStart; } } List<Range> tokenRanges = tokenizer.findTokenRanges(editable, candidateStringStart, candidateStringEnd); for (Range range: tokenRanges) { if (range.start <= cursorEndPosition && cursorEndPosition <= range.end) { return range; } } return new Range(cursorEndPosition, cursorEndPosition); }
Example 13
Source File: RichUtils.java From RichEditor with MIT License | 5 votes |
/** * 处理行内样式各个按钮的状态(点亮或置灰) * * @param type 样式类型 */ private boolean handleInlineStyleButtonStatus(@RichTypeEnum String type) { Editable editable = mRichEditText.getEditableText(); int cursorPos = mRichEditText.getSelectionEnd(); IInlineSpan[] inlineSpans = (IInlineSpan[]) editable.getSpans(cursorPos, cursorPos, getSpanClassFromType(type)); if (inlineSpans.length <= 0) { return false; } boolean isLight = false; //是否点亮 for (IInlineSpan span : inlineSpans) { int spanStart = editable.getSpanStart(span); int spanEnd = editable.getSpanEnd(span); int spanFlag = editable.getSpanFlags(span); if (spanStart < cursorPos && spanEnd > cursorPos) { isLight = true; } else if (spanStart == cursorPos && (spanFlag == Spanned.SPAN_INCLUSIVE_INCLUSIVE || spanFlag == Spanned.SPAN_INCLUSIVE_EXCLUSIVE)) { isLight = true; } else if (spanEnd == cursorPos && (spanFlag == Spanned.SPAN_INCLUSIVE_INCLUSIVE || spanFlag == Spanned.SPAN_EXCLUSIVE_INCLUSIVE)) { isLight = true; } } return isLight; }
Example 14
Source File: TokenCompleteTextView.java From SocialTokenAutoComplete with Apache License 2.0 | 5 votes |
public void onClick() { Editable text = getText(); if (text == null) return; switch (tokenClickStyle) { case Select: case SelectDeselect: if (!view.isSelected()) { clearSelections(); view.setSelected(true); break; } if (tokenClickStyle == TokenClickStyle.SelectDeselect) { view.setSelected(false); invalidate(); break; } //If the view is already selected, we want to delete it case Delete: removeSpan(this); break; case None: default: if (getSelectionStart() != text.getSpanEnd(this) + 1) { //Make sure the selection is not in the middle of the span setSelection(text.getSpanEnd(this) + 1); } } }
Example 15
Source File: ContactEditText.java From material with Apache License 2.0 | 5 votes |
private void replaceSpan(RecipientSpan span, Recipient newRecipient){ Editable text = getText(); int start = text.getSpanStart(span); int end = text.getSpanEnd(span); String replace = newRecipient.number; text.replace(start, end - 2, newRecipient.number, 0, replace.length()); span.setRecipient(newRecipient); text.setSpan(span, start, start + replace.length() + 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); }
Example 16
Source File: FixedURLSpan.java From Pix-Art-Messenger with GNU General Public License v3.0 | 5 votes |
public static void fix(final Editable editable) { for (final URLSpan urlspan : editable.getSpans(0, editable.length() - 1, URLSpan.class)) { final int start = editable.getSpanStart(urlspan); final int end = editable.getSpanEnd(urlspan); editable.removeSpan(urlspan); editable.setSpan(new FixedURLSpan(urlspan.getURL()), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } }
Example 17
Source File: TokenCompleteTextView.java From TokenAutoComplete with Apache License 2.0 | 5 votes |
@SuppressWarnings("WeakerAccess") public void onClick() { Editable text = getText(); if (text == null) return; switch (tokenClickStyle) { case Select: case SelectDeselect: if (!view.isSelected()) { clearSelections(); view.setSelected(true); break; } if (tokenClickStyle == TokenClickStyle.SelectDeselect || !isTokenRemovable(token)) { view.setSelected(false); invalidate(); break; } //If the view is already selected, we want to delete it case Delete: if (isTokenRemovable(token)) { removeSpan(text, this); } break; case None: default: if (getSelectionStart() != text.getSpanEnd(this)) { //Make sure the selection is not in the middle of the span setSelection(text.getSpanEnd(this)); } } }
Example 18
Source File: SpellChecker.java From android_9.0.0_r45 with Apache License 2.0 | 4 votes |
private void spellCheck() { if (mSpellCheckerSession == null) return; Editable editable = (Editable) mTextView.getText(); final int selectionStart = Selection.getSelectionStart(editable); final int selectionEnd = Selection.getSelectionEnd(editable); TextInfo[] textInfos = new TextInfo[mLength]; int textInfosCount = 0; for (int i = 0; i < mLength; i++) { final SpellCheckSpan spellCheckSpan = mSpellCheckSpans[i]; if (mIds[i] < 0 || spellCheckSpan.isSpellCheckInProgress()) continue; final int start = editable.getSpanStart(spellCheckSpan); final int end = editable.getSpanEnd(spellCheckSpan); // Do not check this word if the user is currently editing it final boolean isEditing; // Defer spell check when typing a word ending with a punctuation like an apostrophe // which could end up being a mid-word punctuation. if (selectionStart == end + 1 && WordIterator.isMidWordPunctuation( mCurrentLocale, Character.codePointBefore(editable, end + 1))) { isEditing = false; } else if (mIsSentenceSpellCheckSupported) { // Allow the overlap of the cursor and the first boundary of the spell check span // no to skip the spell check of the following word because the // following word will never be spell-checked even if the user finishes composing isEditing = selectionEnd <= start || selectionStart > end; } else { isEditing = selectionEnd < start || selectionStart > end; } if (start >= 0 && end > start && isEditing) { spellCheckSpan.setSpellCheckInProgress(true); final TextInfo textInfo = new TextInfo(editable, start, end, mCookie, mIds[i]); textInfos[textInfosCount++] = textInfo; if (DBG) { Log.d(TAG, "create TextInfo: (" + i + "/" + mLength + ") text = " + textInfo.getSequence() + ", cookie = " + mCookie + ", seq = " + mIds[i] + ", sel start = " + selectionStart + ", sel end = " + selectionEnd + ", start = " + start + ", end = " + end); } } } if (textInfosCount > 0) { if (textInfosCount < textInfos.length) { TextInfo[] textInfosCopy = new TextInfo[textInfosCount]; System.arraycopy(textInfos, 0, textInfosCopy, 0, textInfosCount); textInfos = textInfosCopy; } if (mIsSentenceSpellCheckSupported) { mSpellCheckerSession.getSentenceSuggestions( textInfos, SuggestionSpan.SUGGESTIONS_MAX_SIZE); } else { mSpellCheckerSession.getSuggestions(textInfos, SuggestionSpan.SUGGESTIONS_MAX_SIZE, false /* TODO Set sequentialWords to true for initial spell check */); } } }
Example 19
Source File: MentionsEditText.java From Spyglass with Apache License 2.0 | 4 votes |
/** * Ensures that the text within each {@link MentionSpan} in the {@link Editable} correctly * matches what it should be outputting. If not, replace it with the correct value. * * @param text the {@link Editable} to examine */ private void ensureMentionSpanIntegrity(Editable text) { if (text == null) { return; } MentionSpan[] spans = text.getSpans(0, text.length(), MentionSpan.class); boolean spanAltered = false; for (MentionSpan span : spans) { int start = text.getSpanStart(span); int end = text.getSpanEnd(span); CharSequence spanText = text.subSequence(start, end).toString(); Mentionable.MentionDisplayMode displayMode = span.getDisplayMode(); switch (displayMode) { case PARTIAL: case FULL: String name = span.getDisplayString(); if (!name.contentEquals(spanText) && start >= 0 && start < end && end <= text.length()) { // Mention display name does not match what is being shown, // replace text in span with proper display name int cursor = getSelectionStart(); int diff = cursor - end; text.removeSpan(span); text.replace(start, end, name); if (diff > 0 && start + end + diff < text.length()) { text.replace(start + end, start + end + diff, ""); } if (name.length() > 0) { text.setSpan(span, start, start + name.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } // Notify for partially deleted mentions. if (mMentionWatchers.size() > 0 && displayMode == Mentionable.MentionDisplayMode.PARTIAL) { notifyMentionPartiallyDeletedWatchers(span.getMention(), name, start, end); } spanAltered = true; } break; case NONE: default: // Mention with DisplayMode == NONE should be deleted from the text boolean hasListeners = mMentionWatchers.size() > 0; final String textBeforeDelete = hasListeners ? text.toString() : null; text.delete(start, end); setSelection(start); if (hasListeners) { notifyMentionDeletedWatchers(span.getMention(), textBeforeDelete, start, end); } spanAltered = true; break; } } // Reset input method if spans have been changed (updates suggestions) if (spanAltered) { restartInput(); } }
Example 20
Source File: TokenCompleteTextView.java From SocialTokenAutoComplete with Apache License 2.0 | 4 votes |
private void updateHint() { Editable text = getText(); CharSequence hintText = getHint(); if (text == null || hintText == null) { return; } //Show hint if we need to if (prefix.length() > 0) { HintSpan[] hints = text.getSpans(0, text.length(), HintSpan.class); HintSpan hint = null; int testLength = prefix.length(); if (hints.length > 0) { hint = hints[0]; testLength += text.getSpanEnd(hint) - text.getSpanStart(hint); } if (text.length() == testLength) { hintVisible = true; if (hint != null) { return;//hint already visible } //We need to display the hint manually Typeface tf = getTypeface(); int style = Typeface.NORMAL; if (tf != null) { style = tf.getStyle(); } ColorStateList colors = getHintTextColors(); HintSpan hintSpan = new HintSpan(null, style, (int)getTextSize(), colors, colors); text.insert(prefix.length(), hintText); text.setSpan(hintSpan, prefix.length(), prefix.length() + getHint().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); setSelection(prefix.length()); } else { if (hint == null) { return; //hint already removed } //Remove the hint. There should only ever be one int sStart = text.getSpanStart(hint); int sEnd = text.getSpanEnd(hint); text.removeSpan(hint); text.replace(sStart, sEnd, ""); hintVisible = false; } } }