Java Code Examples for android.text.SpannableString#getSpans()

The following examples show how to use android.text.SpannableString#getSpans() . 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: LinkTransformationMethod.java    From natrium-android-wallet with BSD 2-Clause "Simplified" License 6 votes vote down vote up
@Override
public CharSequence getTransformation(CharSequence source, View view) {
    if (view instanceof TextView) {
        TextView textView = (TextView) view;
        if (textView.getText() == null || !(textView.getText() instanceof Spannable)) {
            return source;
        }
        SpannableString text = (SpannableString) textView.getText();
        URLSpan[] spans = text.getSpans(0, textView.length(), URLSpan.class);
        for (int i = spans.length - 1; i >= 0; i--) {
            URLSpan oldSpan = spans[i];
            int start = text.getSpanStart(oldSpan);
            int end = text.getSpanEnd(oldSpan);
            String url = oldSpan.getURL();
            text.removeSpan(oldSpan);
            text.setSpan(new CustomUrlSpan(url), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        return text;
    }
    return source;
}
 
Example 2
Source File: LinkTransformationMethod.java    From nano-wallet-android with BSD 2-Clause "Simplified" License 6 votes vote down vote up
@Override
public CharSequence getTransformation(CharSequence source, View view) {
    if (view instanceof TextView) {
        TextView textView = (TextView) view;
         if (textView.getText() == null || !(textView.getText() instanceof Spannable)) {
            return source;
        }
        SpannableString text = (SpannableString) textView.getText();
        URLSpan[] spans = text.getSpans(0, textView.length(), URLSpan.class);
        for (int i = spans.length - 1; i >= 0; i--) {
            URLSpan oldSpan = spans[i];
            int start = text.getSpanStart(oldSpan);
            int end = text.getSpanEnd(oldSpan);
            String url = oldSpan.getURL();
            text.removeSpan(oldSpan);
            text.setSpan(new CustomUrlSpan(url), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        return text;
    }
    return source;
}
 
Example 3
Source File: SpannableUtils.java    From talkback with Apache License 2.0 6 votes vote down vote up
/**
 * Retrieves SpannableString containing the target span in the accessibility node. The content
 * description and text of the node is checked in order.
 *
 * @param node The AccessibilityNodeInfoCompat where the text comes from.
 * @param spanClass Class of target span.
 * @return SpannableString with at least 1 target span. null if no target span found in the node.
 */
public static <T> @Nullable SpannableString getStringWithTargetSpan(
    AccessibilityNodeInfoCompat node, Class<T> spanClass) {

  CharSequence text = node.getContentDescription();
  if (isEmptyOrNotSpannableStringType(text)) {
    text = AccessibilityNodeInfoUtils.getText(node);
    if (isEmptyOrNotSpannableStringType(text)) {
      return null;
    }
  }

  SpannableString spannable = SpannableString.valueOf(text);
  T[] spans = spannable.getSpans(0, spannable.length(), spanClass);
  if (spans == null || spans.length == 0) {
    return null;
  }

  return spannable;
}
 
Example 4
Source File: ImeAdapter.java    From 365browser with Apache License 2.0 6 votes vote down vote up
@CalledByNative
private void populateUnderlinesFromSpans(CharSequence text, long underlines) {
    if (DEBUG_LOGS) {
        Log.i(TAG, "populateUnderlinesFromSpans: text [%s], underlines [%d]", text, underlines);
    }
    if (!(text instanceof SpannableString)) return;

    SpannableString spannableString = ((SpannableString) text);
    CharacterStyle spans[] =
            spannableString.getSpans(0, text.length(), CharacterStyle.class);
    for (CharacterStyle span : spans) {
        if (span instanceof BackgroundColorSpan) {
            nativeAppendBackgroundColorSpan(underlines, spannableString.getSpanStart(span),
                    spannableString.getSpanEnd(span),
                    ((BackgroundColorSpan) span).getBackgroundColor());
        } else if (span instanceof UnderlineSpan) {
            nativeAppendUnderlineSpan(underlines, spannableString.getSpanStart(span),
                    spannableString.getSpanEnd(span));
        }
    }
}
 
Example 5
Source File: SmallAnimatedTextView.java    From tilt-game-android with MIT License 6 votes vote down vote up
@Override
public void setText(CharSequence text, BufferType type) {
	_newText = new SpannableString(text);
	WordSpan[] spans = _newText.getSpans(0, text.length(), WordSpan.class);

	for (WordSpan span : spans) {
		_newText.removeSpan(span);
	}

	String[] words = text.toString().split(" ");
	int charIndex = 0;
	for (int i = 0; i < words.length; i++) {
		int endWordIndex = charIndex + words[i].length();
		_newText.setSpan(new WordSpan(getTextSize()), charIndex, endWordIndex, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
		charIndex = endWordIndex + 1;
	}

	super.setText(_newText, BufferType.SPANNABLE);
}
 
Example 6
Source File: LinkifyHelper.java    From Zom-Android-XMPP with GNU General Public License v3.0 6 votes vote down vote up
public static <A extends CharacterStyle, B extends CharacterStyle> Spannable replaceAll(
        CharSequence original, Class<A> sourceType, SpanConverter<A, B> converter) {
    SpannableString result = new SpannableString(original);
    A[] spans = result.getSpans(0, result.length(), sourceType);

    for (A span : spans) {
        int start = result.getSpanStart(span);
        int end = result.getSpanEnd(span);
        int flags = result.getSpanFlags(span);

        result.removeSpan(span);
        result.setSpan(converter.convert(span), start, end, flags);
    }

    return (result);
}
 
Example 7
Source File: SpannableSerializer.java    From xDrip-plus with GNU General Public License v3.0 6 votes vote down vote up
private static JSONArray extractClass(final SpannableString ss, final Class<? extends CharacterStyle> clz) {
    val array = new JSONArray();
    val spansBg = ss.getSpans(0, ss.length(), clz);
    for (val span : spansBg) {
        int col;
        switch (clz.getSimpleName()) {
            case "BackgroundColorSpan":
                col = ((BackgroundColorSpan) span).getBackgroundColor();
                break;
            case "ForegroundColorSpan":
                col = ((ForegroundColorSpan) span).getForegroundColor();
                break;
            default:
                throw new RuntimeException("Cant match extract class type: " + clz.getSimpleName());
        }
        pullSpanColor(ss, span, col, array);
    }
    return array;
}
 
Example 8
Source File: SnackbarCustomAssert.java    From SnackbarBuilder with Apache License 2.0 6 votes vote down vote up
public SnackbarCustomAssert hasMessagesAppended(List<Pair<String, Integer>> expected) {
  TextView messageView = (TextView) actual.getView().findViewById(R.id.snackbar_text);
  SpannableString message = SpannableString.valueOf(messageView.getText());
  int size = expected.size();
  for (int i = 0; i < size; i++) {
    Pair<String, Integer> pair = expected.get(i);
    int length = pair.first.length();
    Assertions.assertThat(message.subSequence(0, length).toString()).isEqualTo(pair.first);
    ForegroundColorSpan[] spans = message
        .getSpans(0, length, ForegroundColorSpan.class);
    if (pair.second == 0) {
      Assertions.assertThat(spans).isEmpty();
    } else {
      Assertions.assertThat(spans).hasSize(1);
      Assertions.assertThat(spans[0].getForegroundColor()).isEqualTo(pair.second);
    }
    message = SpannableString.valueOf(message.subSequence(length, message.length()));
  }
  return this;
}
 
Example 9
Source File: LargeAnimatedTextView.java    From tilt-game-android with MIT License 5 votes vote down vote up
@Override
public void setText(CharSequence text, BufferType type) {
	_newText = new SpannableString(text);
	TextChar[] letters = _newText.getSpans(0, _newText.length(), TextChar.class);

	for (TextChar letter : letters) {
		_newText.removeSpan(letter);
	}
	for (int i = 0; i < _newText.length(); i++) {
		_newText.setSpan(new TextChar(getTextSize()), i, i + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
	}

	super.setText(_newText, BufferType.SPANNABLE);
}
 
Example 10
Source File: TextViewWithClickableSpans.java    From 365browser with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the ClickableSpans in this TextView's text.
 */
@VisibleForTesting
public ClickableSpan[] getClickableSpans() {
    CharSequence text = getText();
    if (!(text instanceof SpannableString)) return null;

    SpannableString spannable = (SpannableString) text;
    return spannable.getSpans(0, spannable.length(), ClickableSpan.class);
}
 
Example 11
Source File: SnackbarBuilderTest.java    From SnackbarBuilder with Apache License 2.0 5 votes vote down vote up
@Test
public void givenSpan_whenMessage_thenMessageSet() {
  SnackbarBuilder builder = createBuilder();
  Spannable spannable = new SpannableString("testMessage");
  spannable.setSpan(new ForegroundColorSpan(Color.CYAN), 0, spannable.length(),
      Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

  builder.message(spannable);

  assertThat(builder.message.toString()).isEqualTo("testMessage");
  SpannableString actual = SpannableString.valueOf(builder.message);
  ForegroundColorSpan[] spans = actual.getSpans(0, spannable.length(), ForegroundColorSpan.class);
  assertThat(spans).hasSize(1);
  assertThat(spans[0].getForegroundColor()).isEqualTo(Color.CYAN);
}
 
Example 12
Source File: SpanFormatter.java    From QuickDevFramework with Apache License 2.0 5 votes vote down vote up
private static CharSequence fixSpanColor(CharSequence text) {
	if (text instanceof Spanned) {
		final SpannableString s = new SpannableString(text);
		final ForegroundColorSpan[] spans = s.getSpans(0, s.length(), ForegroundColorSpan.class);
		for (final ForegroundColorSpan oldSpan : spans) {
			final ForegroundColorSpan newSpan = new ForegroundColorSpan(oldSpan.getForegroundColor() | 0xFF000000);
			s.setSpan(newSpan, s.getSpanStart(oldSpan), s.getSpanEnd(oldSpan), s.getSpanFlags(oldSpan));
			s.removeSpan(oldSpan);
		}
		return s;
	} else {
		return text;
	}
}
 
Example 13
Source File: GameActivity.java    From TextFiction with Apache License 2.0 5 votes vote down vote up
/**
 * Add underlines to a text blob. Any existing underlines are removed. before
 * new ones are added.
 * 
 * @param span
 *          the blob to modify
 * @param words
 *          the words to underline (all lowercase!)
 */
private static void highlight(SpannableString span, String... words) {
	UnderlineSpan old[] = span.getSpans(0, span.length(), UnderlineSpan.class);
	for (UnderlineSpan del : old) {
		span.removeSpan(del);
	}
	char spanChars[] = span.toString().toLowerCase().toCharArray();
	for (String word : words) {
		char[] wc = word.toCharArray();
		int last = spanChars.length - wc.length + 1;
		for (int i = 0; i < last; i++) {
			// First check if there is a word-sized gap at spanchars[i] as we don't
			// want to highlight words that are actually just substrings (e.g.
			// "east" in "lEASTwise").
			if ((i > 0 && Character.isLetterOrDigit(spanChars[i - 1]))
					|| (i + wc.length != spanChars.length && Character.isLetterOrDigit(spanChars[i
							+ wc.length]))) {
				continue;
			}
			int a = i;
			int b = 0;
			while (b < wc.length) {
				if (spanChars[a] != wc[b]) {
					b = 0;
					break;
				}
				a++;
				b++;
			}
			if (b == wc.length) {
				span.setSpan(new UnderlineSpan(), i, a, 0);
				i = a;
			}
		}
	}
}
 
Example 14
Source File: TimeLineUtility.java    From SprintNBA with Apache License 2.0 4 votes vote down vote up
public static SpannableString convertNormalStringToSpannableString(String txt, TimeLineStatus status) {
    String hackTxt;
    if (txt.startsWith("[") && txt.endsWith("]")) {
        hackTxt = txt + " ";
    } else {
        hackTxt = txt;
    }

    SpannableString value = SpannableString.valueOf(hackTxt);
    switch (status) {
        case LINK: {
            Linkify.addLinks(value, LinkPatterns.WEB_URL, LinkPatterns.WEB_SCHEME);
        }
        break;
        case FEED: {
            Linkify.addLinks(value, LinkPatterns.WEB_URL, LinkPatterns.WEB_SCHEME);
            Linkify.addLinks(value, LinkPatterns.TOPIC_URL, LinkPatterns.TOPIC_SCHEME);
            Linkify.addLinks(value, LinkPatterns.MENTION_URL, LinkPatterns.MENTION_SCHEME);
        }
        break;
    }

    android.text.style.URLSpan[] urlSpans = value.getSpans(0, value.length(), android.text.style.URLSpan.class);
    URLSpan weiboSpan;

    for (android.text.style.URLSpan urlSpan : urlSpans) {
        if (urlSpan.getURL().startsWith(LinkPatterns.TOPIC_SCHEME)) {
            String topic = urlSpan.getURL().substring(LinkPatterns.TOPIC_SCHEME.length(), urlSpan.getURL().length());
            //不识别空格话题和大于30字话题
            String group = topic.substring(1, topic.length() - 1).trim();
            if (1 > group.length() || group.length() > 30) {
                value.removeSpan(urlSpan);
                continue;
            }
        }
        weiboSpan = new URLSpan(urlSpan.getURL(), mColor);
        int start = value.getSpanStart(urlSpan);
        int end = value.getSpanEnd(urlSpan);
        value.removeSpan(urlSpan);
        value.setSpan(weiboSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }

    return value;
}
 
Example 15
Source File: InputLogic.java    From Indic-Keyboard with Apache License 2.0 4 votes vote down vote up
/**
 * Reverts a previous commit with auto-correction.
 *
 * This is triggered upon pressing backspace just after a commit with auto-correction.
 *
 * @param inputTransaction The transaction in progress.
 * @param settingsValues the current values of the settings.
 */
private void revertCommit(final InputTransaction inputTransaction,
        final SettingsValues settingsValues) {
    Log.d("IndicKeyboard", "InputLogidc: revertCommit");
    final CharSequence originallyTypedWord = mLastComposedWord.mTypedWord;
    final String originallyTypedWordString =
            originallyTypedWord != null ? originallyTypedWord.toString() : "";
    final CharSequence committedWord = mLastComposedWord.mCommittedWord;
    final String committedWordString = committedWord.toString();
    final int cancelLength = committedWord.length();
    final String separatorString = mLastComposedWord.mSeparatorString;
    // If our separator is a space, we won't actually commit it,
    // but set the space state to PHANTOM so that a space will be inserted
    // on the next keypress
    final boolean usePhantomSpace = separatorString.equals(Constants.STRING_SPACE);
    // We want java chars, not codepoints for the following.
    final int separatorLength = separatorString.length();
    // TODO: should we check our saved separator against the actual contents of the text view?
    final int deleteLength = cancelLength + separatorLength;
    if (DebugFlags.DEBUG_ENABLED) {
        if (mWordComposer.isComposingWord()) {
            throw new RuntimeException("revertCommit, but we are composing a word");
        }
        final CharSequence wordBeforeCursor =
                mConnection.getTextBeforeCursor(deleteLength, 0).subSequence(0, cancelLength);
        if (!TextUtils.equals(committedWord, wordBeforeCursor)) {
            throw new RuntimeException("revertCommit check failed: we thought we were "
                    + "reverting \"" + committedWord
                    + "\", but before the cursor we found \"" + wordBeforeCursor + "\"");
        }
    }
    mConnection.deleteTextBeforeCursor(deleteLength);
    if (!TextUtils.isEmpty(committedWord)) {
        unlearnWord(committedWordString, inputTransaction.mSettingsValues,
                Constants.EVENT_REVERT);
    }
    final String stringToCommit = originallyTypedWord +
            (usePhantomSpace ? "" : separatorString);
    final SpannableString textToCommit = new SpannableString(stringToCommit);
    if (committedWord instanceof SpannableString) {
        final SpannableString committedWordWithSuggestionSpans = (SpannableString)committedWord;
        final Object[] spans = committedWordWithSuggestionSpans.getSpans(0,
                committedWord.length(), Object.class);
        final int lastCharIndex = textToCommit.length() - 1;
        // We will collect all suggestions in the following array.
        final ArrayList<String> suggestions = new ArrayList<>();
        // First, add the committed word to the list of suggestions.
        suggestions.add(committedWordString);
        for (final Object span : spans) {
            // If this is a suggestion span, we check that the word is not the committed word.
            // That should mostly be the case.
            // Given this, we add it to the list of suggestions, otherwise we discard it.
            if (span instanceof SuggestionSpan) {
                final SuggestionSpan suggestionSpan = (SuggestionSpan)span;
                for (final String suggestion : suggestionSpan.getSuggestions()) {
                    if (!suggestion.equals(committedWordString)) {
                        suggestions.add(suggestion);
                    }
                }
            } else {
                // If this is not a suggestion span, we just add it as is.
                textToCommit.setSpan(span, 0 /* start */, lastCharIndex /* end */,
                        committedWordWithSuggestionSpans.getSpanFlags(span));
            }
        }
        // Add the suggestion list to the list of suggestions.
        textToCommit.setSpan(new SuggestionSpan(mLatinIME /* context */,
                inputTransaction.mSettingsValues.mLocale,
                suggestions.toArray(new String[suggestions.size()]), 0 /* flags */,
                null /* notificationTargetClass */),
                0 /* start */, lastCharIndex /* end */, 0 /* flags */);
    }

    if (inputTransaction.mSettingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces) {
        mConnection.commitText(textToCommit, 1);
        if (usePhantomSpace) {
            mSpaceState = SpaceState.PHANTOM;
        }
    } else {
        // For languages without spaces, we revert the typed string but the cursor is flush
        // with the typed word, so we need to resume suggestions right away.
        final int[] codePoints = StringUtils.toCodePointArray(stringToCommit);
        mWordComposer.setComposingWord(codePoints,
                mLatinIME.getCoordinatesForCurrentKeyboard(codePoints));
        setComposingTextInternal(textToCommit, 1);
    }
    // Don't restart suggestion yet. We'll restart if the user deletes the separator.
    mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;

    // We have a separator between the word and the cursor: we should show predictions.
    inputTransaction.setRequiresUpdateSuggestions();
}
 
Example 16
Source File: ReviewFragment.java    From AnkiDroid-Wear with GNU General Public License v2.0 4 votes vote down vote up
private Spanned makeSoundIconsClickable(Spanned text, boolean isAnswer) {
        JSONArray sounds = findSounds(isAnswer);
        SpannableString qss = new SpannableString(text);
        int soundIndex = 0;


        ImageSpan[] image_spans = qss.getSpans(0, qss.length(), ImageSpan.class);

        for (ImageSpan span : image_spans) {
            if (span.getSource().equals(SOUND_PLACEHOLDER_STRING)) {

                final String image_src = span.getSource();
                final int start = qss.getSpanStart(span);
                final int end = qss.getSpanEnd(span);


                final String soundName;
                String soundName1 = "";
                if (soundIndex < sounds.length()) {
                    try {
                        soundName1 = sounds.getString(soundIndex);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
                soundName = soundName1;
                soundIndex++;


                ClickableString click_span = new ClickableString(onSoundIconClickListener, soundName);

                //                ClickableSpan[] click_spans = qss.getSpans(start, end,
                // ClickableSpan.class);
                //
                //                if (click_spans.length != 0) {
                //                    // remove all click spans
                //                    for (ClickableSpan c_span : click_spans) {
                //                        qss.removeSpan(c_span);
                //                    }
                //                }


                qss.setSpan(click_span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

            }


//        int soundIndex = 0;
//        for (int i = 0; i < qss.length()-1; i++){
//            if(((int)qss.charAt(i)) == 55357 && ((int)qss.charAt(i+1)) == 56586){
//                String soundName = null;
//                if(soundIndex < sounds.length()){
//                    try {
//                        soundName = sounds.getString(soundIndex);
//                    } catch (JSONException e) {
//                        e.printStackTrace();
//                    }
//                }
//
//                qss.setSpan(new ClickableString(onSoundIconClickListener, soundName), i, i+2, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
//                soundIndex++;
//            }
//        }
        }
        return qss;
    }
 
Example 17
Source File: RuleSpannables.java    From talkback with Apache License 2.0 4 votes vote down vote up
@Override
public List<ContextMenuItem> getMenuItemsForNode(
    TalkBackService service,
    ContextMenuItemBuilder menuItemBuilder,
    AccessibilityNodeInfoCompat node,
    boolean includeAncestors) {
  final List<SpannableString> spannableStrings = new ArrayList<>();

  // Could copy node, and recycle it through *SpanMenuItemClickListener. But the
  // span-click-listener would rarely recycle the node, because most text has no spans, and thus
  // no click listeners to recycle copies. And even nodes with spans usually exit the menu through
  // some other menu-item other than span-click.
  // TODO: Refactor to provide a general menu-cleanup method.
  // TODO: When Robolectric copies extras bundle, add unit test.
  SpannableTraversalUtils.collectSpannableStringsWithTargetSpanInNodeDescriptionTree(
      node, // Root node of description tree
      TARGET_SPAN_CLASS, // Target span class
      spannableStrings // List of SpannableStrings collected
      );

  final List<ContextMenuItem> result = new ArrayList<>();
  for (SpannableString spannable : spannableStrings) {
    if (spannable == null) {
      continue;
    }
    final Object[] spans = spannable.getSpans(0, spannable.length(), TARGET_SPAN_CLASS);
    if ((spans == null) || (spans.length == 0)) {
      continue;
    }
    for (int i = 0; i < spans.length; i++) {
      final Object span = spans[i];
      if (span == null) {
        continue;
      }
      ContextMenuItem menuItem = null;
      if (span instanceof URLSpan) {
        // For ir-relative UrlSpans, open the link with browser directly.
        menuItem =
            createMenuItemForUrlSpan(service, menuItemBuilder, i, spannable, (URLSpan) span);
      }
      // For other kinds of ClickableSpans(including relative UrlSpan) from O, activate it with
      // ClickableSpan.onClick(null).
      if (menuItem == null && span instanceof ClickableSpan) {
        menuItem =
            createMenuItemForClickableSpan(
                service, menuItemBuilder, i, spannable, (ClickableSpan) span);
      }
      if (menuItem != null) {
        result.add(menuItem);
      }
    }
  }
  return result;
}
 
Example 18
Source File: SpannableStringHelper.java    From revolution-irc with GNU General Public License v3.0 4 votes vote down vote up
public static CharSequence copyCharSequence(CharSequence msg) {
    SpannableString str = new SpannableString(msg);
    for (Object o : str.getSpans(0, str.length(), NoCopySpan.class))
        str.removeSpan(o);
    return str;
}
 
Example 19
Source File: InputLogic.java    From AOSP-Kayboard-7.1.2 with Apache License 2.0 4 votes vote down vote up
/**
 * Reverts a previous commit with auto-correction.
 *
 * This is triggered upon pressing backspace just after a commit with auto-correction.
 *
 * @param inputTransaction The transaction in progress.
 * @param settingsValues the current values of the settings.
 */
private void revertCommit(final InputTransaction inputTransaction,
        final SettingsValues settingsValues) {
    final CharSequence originallyTypedWord = mLastComposedWord.mTypedWord;
    final String originallyTypedWordString =
            originallyTypedWord != null ? originallyTypedWord.toString() : "";
    final CharSequence committedWord = mLastComposedWord.mCommittedWord;
    final String committedWordString = committedWord.toString();
    final int cancelLength = committedWord.length();
    final String separatorString = mLastComposedWord.mSeparatorString;
    // If our separator is a space, we won't actually commit it,
    // but set the space state to PHANTOM so that a space will be inserted
    // on the next keypress
    final boolean usePhantomSpace = separatorString.equals(Constants.STRING_SPACE);
    // We want java chars, not codepoints for the following.
    final int separatorLength = separatorString.length();
    // TODO: should we check our saved separator against the actual contents of the text view?
    final int deleteLength = cancelLength + separatorLength;
    if (DebugFlags.DEBUG_ENABLED) {
        if (mWordComposer.isComposingWord()) {
            throw new RuntimeException("revertCommit, but we are composing a word");
        }
        final CharSequence wordBeforeCursor =
                mConnection.getTextBeforeCursor(deleteLength, 0).subSequence(0, cancelLength);
        if (!TextUtils.equals(committedWord, wordBeforeCursor)) {
            throw new RuntimeException("revertCommit check failed: we thought we were "
                    + "reverting \"" + committedWord
                    + "\", but before the cursor we found \"" + wordBeforeCursor + "\"");
        }
    }
    mConnection.deleteTextBeforeCursor(deleteLength);
    if (!TextUtils.isEmpty(committedWord)) {
        unlearnWord(committedWordString, inputTransaction.mSettingsValues,
                Constants.EVENT_REVERT);
    }
    final String stringToCommit = originallyTypedWord +
            (usePhantomSpace ? "" : separatorString);
    final SpannableString textToCommit = new SpannableString(stringToCommit);
    if (committedWord instanceof SpannableString) {
        final SpannableString committedWordWithSuggestionSpans = (SpannableString)committedWord;
        final Object[] spans = committedWordWithSuggestionSpans.getSpans(0,
                committedWord.length(), Object.class);
        final int lastCharIndex = textToCommit.length() - 1;
        // We will collect all suggestions in the following array.
        final ArrayList<String> suggestions = new ArrayList<>();
        // First, add the committed word to the list of suggestions.
        suggestions.add(committedWordString);
        for (final Object span : spans) {
            // If this is a suggestion span, we check that the word is not the committed word.
            // That should mostly be the case.
            // Given this, we add it to the list of suggestions, otherwise we discard it.
            if (span instanceof SuggestionSpan) {
                final SuggestionSpan suggestionSpan = (SuggestionSpan)span;
                for (final String suggestion : suggestionSpan.getSuggestions()) {
                    if (!suggestion.equals(committedWordString)) {
                        suggestions.add(suggestion);
                    }
                }
            } else {
                // If this is not a suggestion span, we just add it as is.
                textToCommit.setSpan(span, 0 /* start */, lastCharIndex /* end */,
                        committedWordWithSuggestionSpans.getSpanFlags(span));
            }
        }
        // Add the suggestion list to the list of suggestions.
        textToCommit.setSpan(new SuggestionSpan(mLatinIME /* context */,
                inputTransaction.mSettingsValues.mLocale,
                suggestions.toArray(new String[suggestions.size()]), 0 /* flags */,
                null /* notificationTargetClass */),
                0 /* start */, lastCharIndex /* end */, 0 /* flags */);
    }

    if (inputTransaction.mSettingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces) {
        mConnection.commitText(textToCommit, 1);
        if (usePhantomSpace) {
            mSpaceState = SpaceState.PHANTOM;
        }
    } else {
        // For languages without spaces, we revert the typed string but the cursor is flush
        // with the typed word, so we need to resume suggestions right away.
        final int[] codePoints = StringUtils.toCodePointArray(stringToCommit);
        mWordComposer.setComposingWord(codePoints,
                mLatinIME.getCoordinatesForCurrentKeyboard(codePoints));
        setComposingTextInternal(textToCommit, 1);
    }
    // Don't restart suggestion yet. We'll restart if the user deletes the separator.
    mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;

    // We have a separator between the word and the cursor: we should show predictions.
    inputTransaction.setRequiresUpdateSuggestions();
}
 
Example 20
Source File: FloatingLabelSpinner.java    From FloatingLabelSpinner with Apache License 2.0 4 votes vote down vote up
private void drawSpannableString(final Canvas canvas, CharSequence hint, final TextPaint paint, final int start_x, final int start_y) {
    // draw each span one at a time
    int next;
    float xStart = start_x;
    float xEnd;

    if (paint != errorPaint)
        hint = TextUtils.ellipsize(hint, paint, getWidth() - padding_left - padding_right - label_horizontal_margin, TextUtils.TruncateAt.END);

    if (hint instanceof SpannableString) {
        SpannableString spannableString = (SpannableString) hint;
        for (int i = 0; i < spannableString.length(); i = next) {

            // find the next span transition
            next = spannableString.nextSpanTransition(i, spannableString.length(), CharacterStyle.class);

            // measure the length of the span
            xEnd = xStart + paint.measureText(spannableString, i, next);

            // draw the highlight (background color) first
            BackgroundColorSpan[] bgSpans = spannableString.getSpans(i, next, BackgroundColorSpan.class);
            if (bgSpans.length > 0) {
                Paint mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
                mHighlightPaint.setColor(bgSpans[0].getBackgroundColor());
                canvas.drawRect(xStart, start_y + paint.getFontMetrics().top, xEnd, start_y + paint.getFontMetrics().bottom, mHighlightPaint);
            }

            // draw the text with an optional foreground color
            ForegroundColorSpan[] fgSpans = spannableString.getSpans(i, next, ForegroundColorSpan.class);
            if (fgSpans.length > 0) {
                int saveColor = paint.getColor();
                paint.setColor(fgSpans[0].getForegroundColor());
                canvas.drawText(spannableString, i, next, xStart, start_y, paint);
                paint.setColor(saveColor);
            } else {
                canvas.drawText(spannableString, i, next, xStart, start_y, paint);
            }

            xStart = xEnd;
        }
    } else {
        canvas.drawText(hint, 0, hint.length(), xStart, start_y, paint);
    }

}