下面列出了android.text.Editable#removeSpan ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void processSup( boolean opening, Editable output) {
int len = output.length();
if(opening) {
//output.setSpan(new AbsoluteSizeSpan(scriptSize,false), len, len, Spannable.SPAN_MARK_MARK);
//output.setSpan(new RelativeSizeSpan(0.5f), len, len, Spannable.SPAN_MARK_MARK);
output.setSpan(new SuperscriptSpan(), len, len, Spannable.SPAN_MARK_MARK);
} else {
Object obj = getLast(output, SuperscriptSpan.class);
int where = output.getSpanStart(obj);
output.removeSpan(obj);
//obj = getLast(output, RelativeSizeSpan.class);
//output.removeSpan(obj);
if (where != len&&where>=0) {
//output.setSpan(new AbsoluteSizeSpan(scriptSize, false), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
output.setSpan(new RelativeSizeSpan(0.7f), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
output.setSpan(new SuperscriptSpan(), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
//obj = getLast(output, AbsoluteSizeSpan.class);
//where = output.getSpanStart(obj);
//output.removeSpan(obj);
//if (where != len) {
// output.setSpan(new AbsoluteSizeSpan(scriptSize, false), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// //output.setSpan(new RelativeSizeSpan(0.5f), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
//}
}
}
/**
* 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()));
}
/**
* 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()));
}
/**
* 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);
}
}
}
public static void formatSignificant(@Nonnull final Editable s,
@Nullable final RelativeSizeSpan
insignificantRelativeSizeSpan) {
s.removeSpan(SIGNIFICANT_SPAN);
if (insignificantRelativeSizeSpan != null) {
s.removeSpan(insignificantRelativeSizeSpan);
}
final Matcher m = P_SIGNIFICANT.matcher(s);
if (m.find()) {
final int pivot = m.group().length();
s.setSpan(SIGNIFICANT_SPAN, 0, pivot,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
if (s.length() > pivot && insignificantRelativeSizeSpan != null) {
s.setSpan(insignificantRelativeSizeSpan, pivot, s.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
class Bullet {}
if (tag.equals("li") && opening) {
output.setSpan(new Bullet(), output.length(), output.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
if (tag.equals("li") && !opening) {
//output.append("\n\n");
output.append("\n");
Bullet[] spans = output.getSpans(0, output.length(), Bullet.class);
if (spans != null) {
Bullet lastMark = spans[spans.length-1];
int start = output.getSpanStart(lastMark);
output.removeSpan(lastMark);
if (start != output.length()) {
output.setSpan(new BulletSpan(), start, output.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
}
}
/**
* {@inheritDoc}
* @param s
*/
@Override
public void afterTextChanged(Editable s) {
for (CharacterStyle style: mLastStyle) {
s.removeSpan(style);
}
List<MarkdownSyntaxModel> models = MarkdownSyntaxGenerator.syntaxModelsForString(s.toString());
if (models.size() == 0) {
return;
}
mLastStyle.clear();
for (MarkdownSyntaxModel model : models) {
MarkdownSyntaxType type = model.getSyntaxType();
Range range = model.getRange();
// CharacterStyle style = MarkdownSyntaxGenerator.styleFromSyntaxType(type);
int low = range.getLower();
int upper = range.getUpper();
// mLastStyle.add(style);
// s.setSpan(style, low, upper, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
private static void removeSpans(Editable editable) {
SpaceSpan[] paddingSpans = editable.getSpans(0, editable.length(), SpaceSpan.class);
for (SpaceSpan span : paddingSpans) {
editable.removeSpan(span);
}
}
private void processCodeTag(boolean opening, Editable output) {
int len = output.length();
if (opening) {
output.setSpan(new TypefaceSpan("monospace"), len, len, Spannable.SPAN_MARK_MARK);
} else {
Object obj = getLast(output, TypefaceSpan.class);
int where = output.getSpanStart(obj);
output.removeSpan(obj);
if (where != len) {
output.setSpan(new TypefaceSpan("monospace"), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
private static void endBlockElement(Editable text) {
Newline n = getLast(text, Newline.class);
if (n != null) {
appendNewlines(text, n.mNumNewlines);
text.removeSpan(n);
}
Alignment a = getLast(text, Alignment.class);
if (a != null) {
setSpanFromMark(text, a, new AlignmentSpan.Standard(a.mAlignment));
}
}
/**
* 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);
}
}
/**
* 删除指定的段落ImageSpan(如已插入的图片、视频封面、自定义view等)
* 场景:用户长按ImageSpan触发弹窗然后点击删除操作
*
* @param blockImageSpan 段落ImageSpan
*/
public void removeBlockImageSpan(BlockImageSpan blockImageSpan) {
Editable editable = mRichEditText.getEditableText();
BlockImageSpan[] blockImageSpans = editable.getSpans(0, editable.length(), BlockImageSpan.class);
for (BlockImageSpan curBlockImageSpan : blockImageSpans) {
if (curBlockImageSpan == blockImageSpan) {
int start = editable.getSpanStart(curBlockImageSpan);
int end = editable.getSpanEnd(curBlockImageSpan);
editable.removeSpan(curBlockImageSpan);
editable.delete(start, end);
break;
}
}
}
/**
* Removes any {@link com.linkedin.android.spyglass.ui.MentionsEditText.DeleteSpan}s and the text within them from
* the given text.
*
* @param text the editable containing DeleteSpans to remove
*/
private void removeTextWithinDeleteSpans(@NonNull Editable text) {
DeleteSpan[] deleteSpans = text.getSpans(0, text.length(), DeleteSpan.class);
for (DeleteSpan span : deleteSpans) {
int spanStart = text.getSpanStart(span);
int spanEnd = text.getSpanEnd(span);
text.replace(spanStart, spanEnd, "");
text.removeSpan(span);
}
}
private void markInvalidWords() {
final Editable e = mMnemonicText.getText();
for (final StrikethroughSpan s : e.getSpans(0, e.length(), StrikethroughSpan.class))
e.removeSpan(s);
int start = 0;
for (final String word : e.toString().split(" ")) {
final int end = start + word.length();
if (!MnemonicHelper.mWords.contains(word))
e.setSpan(new StrikethroughSpan(), start, end, 0);
start = end + 1;
}
}
/**
* 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);
}
}
private static void formatSignificant(Editable s) {
RelativeSizeSpan insignificantRelativeSizeSpan = new RelativeSizeSpan(0.85f);
s.removeSpan(SIGNIFICANT_SPAN);
s.removeSpan(insignificantRelativeSizeSpan);
final Matcher m = P_SIGNIFICANT.matcher(s);
if (m.find())
{
final int pivot = m.group().length();
s.setSpan(SIGNIFICANT_SPAN, 0, pivot, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
if (s.length() > pivot)
s.setSpan(insignificantRelativeSizeSpan, pivot, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
public static void clearMetaKeyState(Editable content, int states) {
if ((states&META_SHIFT_ON) != 0) content.removeSpan(CAP);
if ((states&META_ALT_ON) != 0) content.removeSpan(ALT);
if ((states&META_SYM_ON) != 0) content.removeSpan(SYM);
if ((states&META_SELECTING) != 0) content.removeSpan(SELECTING);
}
private SpellCheckSpan onGetSuggestionsInternal(
SuggestionsInfo suggestionsInfo, int offset, int length) {
if (suggestionsInfo == null || suggestionsInfo.getCookie() != mCookie) {
return null;
}
final Editable editable = (Editable) mTextView.getText();
final int sequenceNumber = suggestionsInfo.getSequence();
for (int k = 0; k < mLength; ++k) {
if (sequenceNumber == mIds[k]) {
final int attributes = suggestionsInfo.getSuggestionsAttributes();
final boolean isInDictionary =
((attributes & SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY) > 0);
final boolean looksLikeTypo =
((attributes & SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO) > 0);
final SpellCheckSpan spellCheckSpan = mSpellCheckSpans[k];
//TODO: we need to change that rule for results from a sentence-level spell
// checker that will probably be in dictionary.
if (!isInDictionary && looksLikeTypo) {
createMisspelledSuggestionSpan(
editable, suggestionsInfo, spellCheckSpan, offset, length);
} else {
// Valid word -- isInDictionary || !looksLikeTypo
if (mIsSentenceSpellCheckSupported) {
// Allow the spell checker to remove existing misspelled span by
// overwriting the span over the same place
final int spellCheckSpanStart = editable.getSpanStart(spellCheckSpan);
final int spellCheckSpanEnd = editable.getSpanEnd(spellCheckSpan);
final int start;
final int end;
if (offset != USE_SPAN_RANGE && length != USE_SPAN_RANGE) {
start = spellCheckSpanStart + offset;
end = start + length;
} else {
start = spellCheckSpanStart;
end = spellCheckSpanEnd;
}
if (spellCheckSpanStart >= 0 && spellCheckSpanEnd > spellCheckSpanStart
&& end > start) {
final Long key = Long.valueOf(TextUtils.packRangeInLong(start, end));
final SuggestionSpan tempSuggestionSpan = mSuggestionSpanCache.get(key);
if (tempSuggestionSpan != null) {
if (DBG) {
Log.i(TAG, "Remove existing misspelled span. "
+ editable.subSequence(start, end));
}
editable.removeSpan(tempSuggestionSpan);
mSuggestionSpanCache.remove(key);
}
}
}
}
return spellCheckSpan;
}
}
return null;
}
private void createMisspelledSuggestionSpan(Editable editable, SuggestionsInfo suggestionsInfo,
SpellCheckSpan spellCheckSpan, int offset, int length) {
final int spellCheckSpanStart = editable.getSpanStart(spellCheckSpan);
final int spellCheckSpanEnd = editable.getSpanEnd(spellCheckSpan);
if (spellCheckSpanStart < 0 || spellCheckSpanEnd <= spellCheckSpanStart)
return; // span was removed in the meantime
final int start;
final int end;
if (offset != USE_SPAN_RANGE && length != USE_SPAN_RANGE) {
start = spellCheckSpanStart + offset;
end = start + length;
} else {
start = spellCheckSpanStart;
end = spellCheckSpanEnd;
}
final int suggestionsCount = suggestionsInfo.getSuggestionsCount();
String[] suggestions;
if (suggestionsCount > 0) {
suggestions = new String[suggestionsCount];
for (int i = 0; i < suggestionsCount; i++) {
suggestions[i] = suggestionsInfo.getSuggestionAt(i);
}
} else {
suggestions = ArrayUtils.emptyArray(String.class);
}
SuggestionSpan suggestionSpan = new SuggestionSpan(mTextView.getContext(), suggestions,
SuggestionSpan.FLAG_EASY_CORRECT | SuggestionSpan.FLAG_MISSPELLED);
// TODO: Remove mIsSentenceSpellCheckSupported by extracting an interface
// to share the logic of word level spell checker and sentence level spell checker
if (mIsSentenceSpellCheckSupported) {
final Long key = Long.valueOf(TextUtils.packRangeInLong(start, end));
final SuggestionSpan tempSuggestionSpan = mSuggestionSpanCache.get(key);
if (tempSuggestionSpan != null) {
if (DBG) {
Log.i(TAG, "Cached span on the same position is cleard. "
+ editable.subSequence(start, end));
}
editable.removeSpan(tempSuggestionSpan);
}
mSuggestionSpanCache.put(key, suggestionSpan);
}
editable.setSpan(suggestionSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTextView.invalidateRegion(start, end, false /* No cursor involved */);
}
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);
internalEditInProgress = true;
text.insert(prefix.length(), hintText);
text.setSpan(hintSpan, prefix.length(), prefix.length() + getHint().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
internalEditInProgress = false;
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);
internalEditInProgress = true;
text.removeSpan(hint);
text.replace(sStart, sEnd, "");
internalEditInProgress = false;
hintVisible = false;
}
}
}