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

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

源代码1 项目: RichEditor   文件: RichTextWatcher.java
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    isDeleteEnterStr = after == 0 && s.length() > 0 && s.charAt(start) == '\n';
    beforeEditContentLen = s.length();
    Editable editable = mEditText.getText();
    int curPos = mEditText.getSelectionStart();

    // 判断是否在图片后输入
    if (curPos == 0) {
        needInsertBreakLinePosAfterImage = -1;
    } else {
        // 判断是否在图片后面输入
        BlockImageSpan[] blockImageSpansAfter = editable.getSpans(curPos - 1, curPos, BlockImageSpan.class);
        if (blockImageSpansAfter.length > 0) {
            //说明当前光标处于imageSpan的后面,如果在当前位置输入文字,需要另起一行
            needInsertBreakLinePosAfterImage = curPos;
        } else {
            needInsertBreakLinePosAfterImage = -1;
        }
    }

    // 判断是否在图片前面输入
    BlockImageSpan[] blockImageSpansBefore = editable.getSpans(curPos, curPos + 1, BlockImageSpan.class);
    // 说明当前光标在ImageSpan的前面
    isNeedInsertBreakLineBeforeImage = blockImageSpansBefore.length > 0;
}
 
源代码2 项目: timecat   文件: UndoRedoHelper.java
/**
 * Perform redo.
 */
public void redo() {
    EditItem edit = mEditHistory.getNext();
    if (edit == null) {
        return;
    }

    Editable text = mTextView.getEditableText();
    int start = edit.mmStart;
    int end = start + (edit.mmBefore != null ? edit.mmBefore.length() : 0);

    mIsUndoOrRedo = true;
    text.replace(start, end, edit.mmAfter);
    mIsUndoOrRedo = false;

    // This will get rid of underlines inserted when editor tries to come
    // up with a suggestion.
    for (Object o : text.getSpans(0, text.length(), UnderlineSpan.class)) {
        text.removeSpan(o);
    }

    Selection.setSelection(text, edit.mmAfter == null ? start
            : (start + edit.mmAfter.length()));
}
 
源代码3 项目: 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);
}
 
源代码4 项目: TokenAutoComplete   文件: TokenCompleteTextView.java
/**
 * Remove an object from the token list. Will remove duplicates if present or do nothing if no
 * object is present in the view. Uses {@link Object#equals(Object)} to find objects. May only
 * be called from the main thread
 *
 * @param object object to remove, may be null or not in the view
 */
@UiThread
public void removeObjectSync(T object) {
    //To make sure all the appropriate callbacks happen, we just want to piggyback on the
    //existing code that handles deleting spans when the text changes
    ArrayList<Editable>texts = new ArrayList<>();
    //If there is hidden content, it's important that we update it first
    if (hiddenContent != null) {
        texts.add(hiddenContent);
    }
    if (getText() != null) {
        texts.add(getText());
    }

    // If the object is currently visible, remove it
    for (Editable text: texts) {
        TokenImageSpan[] spans = text.getSpans(0, text.length(), TokenImageSpan.class);
        for (TokenImageSpan span : spans) {
            if (span.getToken().equals(object)) {
                removeSpan(text, span);
            }
        }
    }

    updateCountSpan();
}
 
源代码5 项目: TokenAutoComplete   文件: TokenCompleteTextView.java
/**
 * Get the list of Tokens
 *
 * @return List of tokens
 */
public List<T> getObjects() {
    ArrayList<T>objects = new ArrayList<>();
    Editable text = getText();
    if (hiddenContent != null) {
        text = hiddenContent;
    }
    for (TokenImageSpan span: text.getSpans(0, text.length(), TokenImageSpan.class)) {
        objects.add(span.getToken());
    }
    return objects;
}
 
源代码6 项目: java-n-IDE-for-Android   文件: HighlightEditor.java
/**
 * highlight find word
 *
 * @param what     - input
 * @param regex    - is java regex
 * @param wordOnly - find word only
 */
public void find(String what, boolean regex, boolean wordOnly, boolean matchCase) {
    Pattern pattern;
    if (regex) {
        if (matchCase) {
            pattern = Pattern.compile(what);
        } else {
            pattern = Pattern.compile(what, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
        }
    } else {
        if (wordOnly) {
            if (matchCase) {
                pattern = Pattern.compile("\\s" + what + "\\s");
            } else {
                pattern = Pattern.compile("\\s" + Pattern.quote(what) + "\\s", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
            }
        } else {
            if (matchCase) {
                pattern = Pattern.compile(Pattern.quote(what));
            } else {
                pattern = Pattern.compile(Pattern.quote(what), Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
            }
        }
    }
    Editable e = getEditableText();
    //remove all span
    BackgroundColorSpan spans[] = e.getSpans(0, e.length(), BackgroundColorSpan.class);
    for (int n = spans.length; n-- > 0; )
        e.removeSpan(spans[n]);
    //set span

    for (Matcher m = pattern.matcher(e); m.find(); ) {
        e.setSpan(new BackgroundColorSpan(codeTheme.getErrorColor()),
                m.start(),
                m.end(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
}
 
源代码7 项目: 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);
}
 
private void findClose(char open, int selEnd) {
    Log.d(TAG, "findClose() called with: open = [" + open + "], selEnd = [" + selEnd + "]");

    Editable text = editText.getText();
    int cursor = selEnd + 1;
    int count = 1;
    char close = getClose(open);

    boolean find = false;
    while (cursor < text.length()) {
        char chatAtCursor = text.charAt(cursor);
        if (chatAtCursor == open) {
            count++;
        } else if (chatAtCursor == close) {
            count--;
        }
        if (count == 0) {
            find = true;
            break;
        }
        cursor++;
    }
    BracketSpan[] spans = text.getSpans(0, text.length(), BracketSpan.class);
    for (BracketSpan span : spans) {
        text.removeSpan(span);
    }
    text.setSpan(new BracketSpan(codeTheme.getBracketColor(),
            codeTheme.getTextColor()), selEnd, selEnd + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    if (find) {
        text.setSpan(new BracketSpan(codeTheme.getBracketColor(),
                codeTheme.getTextColor()), cursor, cursor + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
}
 
private void removeSpan(TokenImageSpan span) {
    Editable text = getText();
    if (text == null) return;

    //If the spanwatcher has been removed, we need to also manually trigger onSpanRemoved
    TokenSpanWatcher[] spans = text.getSpans(0, text.length(), TokenSpanWatcher.class);
    if (spans.length == 0) {
        spanWatcher.onSpanRemoved(text, span, text.getSpanStart(span), text.getSpanEnd(span));
    }

    //Add 1 to the end because we put a " " at the end of the spans when adding them
    text.delete(text.getSpanStart(span), text.getSpanEnd(span) + 1);
}
 
源代码10 项目: google-authenticator-android   文件: Utilities.java
@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
  if ("ul".equalsIgnoreCase(tag)) {
    // Ensure there are at least two newlines both before and after the list.
    ensureAtLeastTwoTrailingNewlines(output);
  } else if ("li".equalsIgnoreCase(tag)) {
    appendNewlineIfNoTrailingNewline(output);
    int outputLength = output.length();
    if (opening) {
      // Attach a BulletSpan to the beginning of the list entry. The span will be removed
      // when processing the closing of this tag/entry.
      output.setSpan(new BulletSpan(), outputLength, outputLength, Spannable.SPAN_MARK_MARK);
    } else {
      // Attach a BulletSpan, spanning the whole list entry. This removes the span
      // attached to the start of this list entry when processing the opening of this tag/entry.
      // We also attach a LeadingMarginSpan to the same location to indent the list entries
      // and their bullets.
      BulletSpan[] bulletSpans = output.getSpans(0, outputLength, BulletSpan.class);
      if (bulletSpans.length > 0) {
        BulletSpan startMarkSpan = bulletSpans[bulletSpans.length - 1];
        int startIndex = output.getSpanStart(startMarkSpan);
        output.removeSpan(startMarkSpan);
        if (startIndex != outputLength) {
          output.setSpan(
              new LeadingMarginSpan.Standard(10),
              startIndex,
              outputLength,
              Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
          output.setSpan(
              new BulletSpan(10),
              startIndex,
              outputLength,
              Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
      }
    }
  }
}
 
源代码11 项目: advanced-textview   文件: FractionActivity.java
private Object getLast(Editable text, Class kind) {
  Object[] objs = text.getSpans(0, text.length(), kind);

  if (objs.length == 0) {
    return null;
  } else {
    for (int i = objs.length - 1; i >= 0; --i) {
      if(text.getSpanFlags(objs[i]) == Spannable.SPAN_MARK_MARK) {
        return objs[i];
      }
    }
    return null;
  }
}
 
源代码12 项目: 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);
        }
    }
}
 
源代码13 项目: TokenAutoComplete   文件: TokenCompleteTextView.java
/**
 * Remove the TextChangedListeners
 */
protected void removeListeners() {
    Editable text = getText();
    if (text != null) {
        TokenSpanWatcher[] spanWatchers = text.getSpans(0, text.length(), TokenSpanWatcher.class);
        for (TokenSpanWatcher watcher : spanWatchers) {
            text.removeSpan(watcher);
        }
        removeTextChangedListener(textWatcher);
    }
}
 
源代码14 项目: Knife   文件: KnifeTagHandler.java
private static Object getLast(Editable text, Class kind) {
    Object[] spans = text.getSpans(0, text.length(), kind);

    if (spans.length == 0) {
        return null;
    } else {
        for (int i = spans.length; i > 0; i--) {
            if (text.getSpanFlags(spans[i - 1]) == Spannable.SPAN_MARK_MARK) {
                return spans[i - 1];
            }
        }

        return null;
    }
}
 
源代码15 项目: Hews   文件: HTMLCodeTagHandler.java
private Object getLast(Editable text, Class kind) {
    Object[] objs = text.getSpans(0, text.length(), kind);
    if (objs.length == 0) {
        return null;
    } else {
        for (int i = objs.length; i > 0; i--) {
            if (text.getSpanFlags(objs[i - 1]) == Spannable.SPAN_MARK_MARK) {
                return objs[i - 1];
            }
        }
        return null;
    }
}
 
源代码16 项目: 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();
    }
}
 
源代码17 项目: nono-android   文件: MyHtmlTagHandler.java
private Object getLast(Editable text, Class kind) {
    Object[] objs = text.getSpans(0, text.length(), kind);

    if (objs.length == 0) {
        return null;
    } else {
        for(int i = objs.length;i>0;i--) {
            if(text.getSpanFlags(objs[i-1]) == Spannable.SPAN_MARK_MARK) {
                return objs[i-1];
            }
        }
        return null;
    }
}
 
源代码18 项目: Spyglass   文件: MentionsEditText.java
/**
 * Replaces any {@link com.linkedin.android.spyglass.ui.MentionsEditText.PlaceholderSpan} within the given text with
 * the {@link MentionSpan} it contains.
 *
 * Note: These PlaceholderSpans are added in {@link #replaceMentionSpansWithPlaceholdersAsNecessary(CharSequence)}
 *
 * @param text the final version of the text after it was changed
 */
private void replacePlaceholdersWithCorrespondingMentionSpans(@NonNull Editable text) {
    PlaceholderSpan[] tempSpans = text.getSpans(0, text.length(), PlaceholderSpan.class);
    for (PlaceholderSpan span : tempSpans) {
        int spanStart = text.getSpanStart(span);
        String mentionDisplayString = span.holder.getDisplayString();
        int end = Math.min(spanStart + mentionDisplayString.length(), text.length());
        text.replace(spanStart, end, mentionDisplayString);
        text.setSpan(span.holder, spanStart, spanStart + mentionDisplayString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        text.removeSpan(span);
    }
}
 
源代码19 项目: Android-RTEditor   文件: ConverterHtmlToText.java
/**
 * Fetch the matching opening Annotation object and verify that it's the one added by us.
 *
 * @param output Spannable string we're working with.
 * @return Starting Annotation object.
 */
private Object getOpeningAnnotation(Editable output) {
    Object[] objs = output.getSpans(0, output.length(), Annotation.class);
    for (int i = objs.length - 1; i >= 0; i--) {
        Annotation span = (Annotation) objs[i];
        if (output.getSpanFlags(objs[i]) == Spanned.SPAN_MARK_MARK
                && span.getKey().equals(IGNORED_ANNOTATION_KEY)
                && span.getValue().equals(IGNORED_ANNOTATION_VALUE)) {
            return objs[i];
        }
    }
    return null;
}
 
源代码20 项目: revolution-irc   文件: TextFormatBar.java
public void updateFormattingAtCursor() {
    if (mEditText == null)
        return;
    Editable text = mEditText.getText();
    int start = mEditText.getSelectionStart();
    int end = mEditText.getSelectionEnd();
    Object[] spans = text.getSpans(start, end, Object.class);

    mBoldButton.setSelected(false);
    mItalicButton.setSelected(false);
    mUnderlineButton.setSelected(false);

    int fgColor = -1;
    int bgColor = -1;

    for (Object span : spans) {
        if (!SpannableStringHelper.checkSpanInclude(text, span, start, end) ||
                (text.getSpanFlags(span) & Spanned.SPAN_COMPOSING) != 0)
            continue;
        if (span instanceof StyleSpan) {
            int style = ((StyleSpan) span).getStyle();
            if (style == Typeface.BOLD)
                mBoldButton.setSelected(true);
            else if (style == Typeface.ITALIC)
                mItalicButton.setSelected(true);
        } else if (span instanceof UnderlineSpan) {
            mUnderlineButton.setSelected(true);
        } else if (span instanceof ForegroundColorSpan) {
            fgColor = ((ForegroundColorSpan) span).getForegroundColor();
        } else if (span instanceof BackgroundColorSpan) {
            bgColor = ((BackgroundColorSpan) span).getBackgroundColor();
        }
    }

    ImageViewCompat.setImageTintList(mTextColorValue, fgColor != -1
            ? ColorStateList.valueOf(fgColor) : mTextColorValueDefault);
    ImageViewCompat.setImageTintList(mFillColorValue, bgColor != -1
            ? ColorStateList.valueOf(bgColor) : mFillColorValueDefault);
}