android.text.Editable#getSpanEnd ( )源码实例Demo

下面列出了android.text.Editable#getSpanEnd ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: TokenAutoComplete   文件: TokenCompleteTextView.java
@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;
    }
}
 
源代码2 项目: TokenAutoComplete   文件: TokenCompleteTextView.java
/**
 * 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();
    }
}
 
源代码3 项目: o2oa   文件: RichEditText.java
@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);
        }
    }
}
 
源代码4 项目: Spyglass   文件: MentionsEditText.java
/**
 * 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);
        }
    }
}
 
源代码5 项目: Carbon   文件: AutoCompleteEditText.java
@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);
}
 
源代码6 项目: TokenAutoComplete   文件: TokenCompleteTextView.java
@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));
            }
    }
}
 
源代码7 项目: Pix-Art-Messenger   文件: FixedURLSpan.java
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);
    }
}
 
源代码8 项目: material   文件: ContactEditText.java
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);
}
 
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);
            }
    }
}
 
源代码10 项目: RichEditor   文件: RichUtils.java
/**
 * 处理行内样式各个按钮的状态(点亮或置灰)
 *
 * @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;
}
 
源代码11 项目: TokenAutoComplete   文件: TokenCompleteTextView.java
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);
}
 
源代码12 项目: Conversations   文件: FixedURLSpan.java
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);
	}
}
 
源代码13 项目: TelePlus-Android   文件: EditTextCaption.java
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();
    }
}
 
源代码14 项目: Spyglass   文件: MentionsEditText.java
/**
 * 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;
}
 
源代码15 项目: actor-platform   文件: GroupUsersFragment.java
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();
    }
}
 
源代码16 项目: YCCustomText   文件: NormalStyle.java
/**
 * 样式情况判断
 * @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);
        }
    }
}
 
源代码17 项目: TokenAutoComplete   文件: TokenCompleteTextView.java
/**
 * 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;
}
 
源代码18 项目: android_9.0.0_r45   文件: SpellChecker.java
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 */);
        }
    }
}
 
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;
        }
    }
}
 
源代码20 项目: Spyglass   文件: MentionsEditText.java
/**
 * 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();
    }
}