use of android.text.Spannable in project android_frameworks_base by ResurrectionRemix.
the class TextView method onSaveInstanceState.
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
// Save state if we are forced to
final boolean freezesText = getFreezesText();
boolean hasSelection = false;
int start = -1;
int end = -1;
if (mText != null) {
start = getSelectionStart();
end = getSelectionEnd();
if (start >= 0 || end >= 0) {
// Or save state if there is a selection
hasSelection = true;
}
}
if (freezesText || hasSelection) {
SavedState ss = new SavedState(superState);
if (freezesText) {
if (mText instanceof Spanned) {
final Spannable sp = new SpannableStringBuilder(mText);
if (mEditor != null) {
removeMisspelledSpans(sp);
sp.removeSpan(mEditor.mSuggestionRangeSpan);
}
ss.text = sp;
} else {
ss.text = mText.toString();
}
}
if (hasSelection) {
// XXX Should also save the current scroll position!
ss.selStart = start;
ss.selEnd = end;
}
if (isFocused() && start >= 0 && end >= 0) {
ss.frozenWithFocus = true;
}
ss.error = getError();
if (mEditor != null) {
ss.editorState = mEditor.saveInstanceState();
}
return ss;
}
return superState;
}
use of android.text.Spannable in project android_frameworks_base by ResurrectionRemix.
the class TextView method setExtractedText.
/**
* Apply to this text view the given extracted text, as previously
* returned by {@link #extractText(ExtractedTextRequest, ExtractedText)}.
*/
public void setExtractedText(ExtractedText text) {
Editable content = getEditableText();
if (text.text != null) {
if (content == null) {
setText(text.text, TextView.BufferType.EDITABLE);
} else {
int start = 0;
int end = content.length();
if (text.partialStartOffset >= 0) {
final int N = content.length();
start = text.partialStartOffset;
if (start > N)
start = N;
end = text.partialEndOffset;
if (end > N)
end = N;
}
removeParcelableSpans(content, start, end);
if (TextUtils.equals(content.subSequence(start, end), text.text)) {
if (text.text instanceof Spanned) {
// OK to copy spans only.
TextUtils.copySpansFrom((Spanned) text.text, 0, end - start, Object.class, content, start);
}
} else {
content.replace(start, end, text.text);
}
}
}
// Now set the selection position... make sure it is in range, to
// avoid crashes. If this is a partial update, it is possible that
// the underlying text may have changed, causing us problems here.
// Also we just don't want to trust clients to do the right thing.
Spannable sp = (Spannable) getText();
final int N = sp.length();
int start = text.selectionStart;
if (start < 0)
start = 0;
else if (start > N)
start = N;
int end = text.selectionEnd;
if (end < 0)
end = 0;
else if (end > N)
end = N;
Selection.setSelection(sp, start, end);
// Finally, update the selection mode.
if ((text.flags & ExtractedText.FLAG_SELECTING) != 0) {
MetaKeyKeyListener.startSelecting(this, sp);
} else {
MetaKeyKeyListener.stopSelecting(this, sp);
}
}
use of android.text.Spannable in project android_frameworks_base by ResurrectionRemix.
the class SpannableTest method testGetSpans.
@MediumTest
public void testGetSpans() {
Spannable spannable = newSpannableWithText("abcdef");
Object emptySpan = new Object();
spannable.setSpan(emptySpan, 1, 1, 0);
Object unemptySpan = new Object();
spannable.setSpan(unemptySpan, 1, 2, 0);
Object[] spans;
// Empty spans are included when they merely abut the query region
// but other spans are not, unless the query region is empty, in
// in which case any abutting spans are returned.
spans = spannable.getSpans(0, 1, Object.class);
MoreAsserts.assertEquals(new Object[] { emptySpan }, spans);
spans = spannable.getSpans(0, 2, Object.class);
MoreAsserts.assertEquals(new Object[] { emptySpan, unemptySpan }, spans);
spans = spannable.getSpans(1, 2, Object.class);
MoreAsserts.assertEquals(new Object[] { emptySpan, unemptySpan }, spans);
spans = spannable.getSpans(2, 2, Object.class);
MoreAsserts.assertEquals(new Object[] { unemptySpan }, spans);
}
use of android.text.Spannable in project android_frameworks_base by ResurrectionRemix.
the class Editor method downgradeEasyCorrectionSpans.
/**
* Downgrades to simple suggestions all the easy correction spans that are not a spell check
* span.
*/
private void downgradeEasyCorrectionSpans() {
CharSequence text = mTextView.getText();
if (text instanceof Spannable) {
Spannable spannable = (Spannable) text;
SuggestionSpan[] suggestionSpans = spannable.getSpans(0, spannable.length(), SuggestionSpan.class);
for (int i = 0; i < suggestionSpans.length; i++) {
int flags = suggestionSpans[i].getFlags();
if ((flags & SuggestionSpan.FLAG_EASY_CORRECT) != 0 && (flags & SuggestionSpan.FLAG_MISSPELLED) == 0) {
flags &= ~SuggestionSpan.FLAG_EASY_CORRECT;
suggestionSpans[i].setFlags(flags);
}
}
}
}
use of android.text.Spannable in project android_frameworks_base by ResurrectionRemix.
the class Editor method shouldOfferToShowSuggestions.
/**
* @return <code>true</code> if it's reasonable to offer to show suggestions depending on
* the current cursor position or selection range. This method is consistent with the
* method to show suggestions {@link SuggestionsPopupWindow#updateSuggestions}.
*/
private boolean shouldOfferToShowSuggestions() {
CharSequence text = mTextView.getText();
if (!(text instanceof Spannable))
return false;
final Spannable spannable = (Spannable) text;
final int selectionStart = mTextView.getSelectionStart();
final int selectionEnd = mTextView.getSelectionEnd();
final SuggestionSpan[] suggestionSpans = spannable.getSpans(selectionStart, selectionEnd, SuggestionSpan.class);
if (suggestionSpans.length == 0) {
return false;
}
if (selectionStart == selectionEnd) {
// Spans overlap the cursor.
for (int i = 0; i < suggestionSpans.length; i++) {
if (suggestionSpans[i].getSuggestions().length > 0) {
return true;
}
}
return false;
}
int minSpanStart = mTextView.getText().length();
int maxSpanEnd = 0;
int unionOfSpansCoveringSelectionStartStart = mTextView.getText().length();
int unionOfSpansCoveringSelectionStartEnd = 0;
boolean hasValidSuggestions = false;
for (int i = 0; i < suggestionSpans.length; i++) {
final int spanStart = spannable.getSpanStart(suggestionSpans[i]);
final int spanEnd = spannable.getSpanEnd(suggestionSpans[i]);
minSpanStart = Math.min(minSpanStart, spanStart);
maxSpanEnd = Math.max(maxSpanEnd, spanEnd);
if (selectionStart < spanStart || selectionStart > spanEnd) {
// The span doesn't cover the current selection start point.
continue;
}
hasValidSuggestions = hasValidSuggestions || suggestionSpans[i].getSuggestions().length > 0;
unionOfSpansCoveringSelectionStartStart = Math.min(unionOfSpansCoveringSelectionStartStart, spanStart);
unionOfSpansCoveringSelectionStartEnd = Math.max(unionOfSpansCoveringSelectionStartEnd, spanEnd);
}
if (!hasValidSuggestions) {
return false;
}
if (unionOfSpansCoveringSelectionStartStart >= unionOfSpansCoveringSelectionStartEnd) {
// No spans cover the selection start point.
return false;
}
if (minSpanStart < unionOfSpansCoveringSelectionStartStart || maxSpanEnd > unionOfSpansCoveringSelectionStartEnd) {
// to show suggestions as it's confusing.
return false;
}
return true;
}
Aggregations