use of android.text.style.CharacterStyle in project little-bear-dictionary by daimajia.
the class QueryProcessor method processOneItem.
/**
* 对每一个单词条目生成textview
*
* @param context
* @param cursor
* @param dictionaryParseInfomation
* @param index
* @return
*/
private TextView processOneItem(Context context, Cursor cursor, DictionaryParseInfomation dictionaryParseInfomation, int index) {
LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
TextView textView = new TextView(context);
for (EchoViews echoView : dictionaryParseInfomation.echoViews) {
textView.setLayoutParams(layoutParams);
textView.setPadding(DisplayUtils.dip2px(context, echoView.view_padding_left), DisplayUtils.dip2px(context, echoView.view_padding_top), DisplayUtils.dip2px(context, echoView.view_padding_right), DisplayUtils.dip2px(context, echoView.view_padding_bottom));
ArrayList<SpannableString> contents = new ArrayList<SpannableString>();
CharacterStyle colorCharacterStyle = null, sizeCharacterStyle = null;
for (TextArg textArg : echoView.sprintfArgs) {
String content = cursor.getString(cursor.getColumnIndex(textArg.argContent)) + " ";
SpannableString partString = dealAction(textArg, content);
colorCharacterStyle = null;
sizeCharacterStyle = null;
if (mIsGlobal) {
colorCharacterStyle = new ForegroundColorSpan(mGlobalColor);
sizeCharacterStyle = new AbsoluteSizeSpan(mGlobalSize);
}
if (mIsIndividual) {
if (mIsIndividualProperty && textArg.type.equalsIgnoreCase("property")) {
colorCharacterStyle = new ForegroundColorSpan(mPropertyColor);
sizeCharacterStyle = new AbsoluteSizeSpan(mPropertySize);
} else if (mIsIndividualEnglish && textArg.type.equalsIgnoreCase("english")) {
colorCharacterStyle = new ForegroundColorSpan(mEnglishColor);
sizeCharacterStyle = new AbsoluteSizeSpan(mEnglishSize);
} else if (mIsIndividualChinese && textArg.type.equalsIgnoreCase("chinese")) {
colorCharacterStyle = new ForegroundColorSpan(mChineseColor);
sizeCharacterStyle = new AbsoluteSizeSpan(mChineseSize);
} else if (mIsIndividualExample && textArg.type.equalsIgnoreCase("example")) {
colorCharacterStyle = new ForegroundColorSpan(mExampleColor);
sizeCharacterStyle = new AbsoluteSizeSpan(mExampleSize);
}
}
if (colorCharacterStyle == null || sizeCharacterStyle == null) {
if (mIsGlobal) {
colorCharacterStyle = new ForegroundColorSpan(mGlobalColor);
sizeCharacterStyle = new AbsoluteSizeSpan(mGlobalSize);
} else {
// theme style
}
}
partString.setSpan(colorCharacterStyle, 0, partString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
partString.setSpan(sizeCharacterStyle, 0, partString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
contents.add(partString);
}
CharSequence resultContent = TextUtils.concat(contents.toArray(new SpannableString[0]));
SpannableString IndexSpannableString = new SpannableString(index + ".");
if (mIsIndividual && mIsIndividualTermNum) {
colorCharacterStyle = new ForegroundColorSpan(mTermNumColor);
sizeCharacterStyle = new AbsoluteSizeSpan(mTermNumSize);
} else if (mIsGlobal) {
colorCharacterStyle = new ForegroundColorSpan(mGlobalColor);
sizeCharacterStyle = new AbsoluteSizeSpan(mGlobalSize);
} else {
// Theme style
}
IndexSpannableString.setSpan(colorCharacterStyle, 0, IndexSpannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
IndexSpannableString.setSpan(sizeCharacterStyle, 0, IndexSpannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
resultContent = TextUtils.concat(IndexSpannableString, resultContent);
textView.setText(resultContent);
}
return textView;
}
use of android.text.style.CharacterStyle in project Klyph by jonathangerbaud.
the class TextViewUtil method setTextClickableForTags.
/**
* Make a clickable for the tags in parameters
* If callback is null, TextViewUtil.onTagClick is called
*/
public static void setTextClickableForTags(final Context context, TextView textView, Map<String, List<Tag>> tags, final TagCallback callback, boolean clickable) {
SpannableStringBuilder strBuilder = new SpannableStringBuilder(textView.getText());
for (final List<Tag> tagList : tags.values()) {
if (tagList.size() > 0) {
CharacterStyle span;
if (clickable) {
span = new ClickableSpan() {
@Override
public void onClick(View widget) {
if (callback != null)
callback.onTagClick(tagList);
else
onTagClick(context, tagList);
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setFakeBoldText(true);
}
};
} else {
span = new StyleSpan(Typeface.BOLD);
}
Tag tag = tagList.get(0);
strBuilder.setSpan(span, tag.getOffset(), tag.getOffset() + tag.getLength(), 0);
}
}
textView.setText(strBuilder);
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
use of android.text.style.CharacterStyle in project platform_frameworks_base by android.
the class TextView method spanChange.
/**
* Not private so it can be called from an inner class without going
* through a thunk.
*/
void spanChange(Spanned buf, Object what, int oldStart, int newStart, int oldEnd, int newEnd) {
// XXX Make the start and end move together if this ends up
// spending too much time invalidating.
boolean selChanged = false;
int newSelStart = -1, newSelEnd = -1;
final Editor.InputMethodState ims = mEditor == null ? null : mEditor.mInputMethodState;
if (what == Selection.SELECTION_END) {
selChanged = true;
newSelEnd = newStart;
if (oldStart >= 0 || newStart >= 0) {
invalidateCursor(Selection.getSelectionStart(buf), oldStart, newStart);
checkForResize();
registerForPreDraw();
if (mEditor != null)
mEditor.makeBlink();
}
}
if (what == Selection.SELECTION_START) {
selChanged = true;
newSelStart = newStart;
if (oldStart >= 0 || newStart >= 0) {
int end = Selection.getSelectionEnd(buf);
invalidateCursor(end, oldStart, newStart);
}
}
if (selChanged) {
mHighlightPathBogus = true;
if (mEditor != null && !isFocused())
mEditor.mSelectionMoved = true;
if ((buf.getSpanFlags(what) & Spanned.SPAN_INTERMEDIATE) == 0) {
if (newSelStart < 0) {
newSelStart = Selection.getSelectionStart(buf);
}
if (newSelEnd < 0) {
newSelEnd = Selection.getSelectionEnd(buf);
}
if (mEditor != null) {
mEditor.refreshTextActionMode();
if (!hasSelection() && mEditor.mTextActionMode == null && hasTransientState()) {
// User generated selection has been removed.
setHasTransientState(false);
}
}
onSelectionChanged(newSelStart, newSelEnd);
}
}
if (what instanceof UpdateAppearance || what instanceof ParagraphStyle || what instanceof CharacterStyle) {
if (ims == null || ims.mBatchEditNesting == 0) {
invalidate();
mHighlightPathBogus = true;
checkForResize();
} else {
ims.mContentChanged = true;
}
if (mEditor != null) {
if (oldStart >= 0)
mEditor.invalidateTextDisplayList(mLayout, oldStart, oldEnd);
if (newStart >= 0)
mEditor.invalidateTextDisplayList(mLayout, newStart, newEnd);
mEditor.invalidateHandlesAndActionMode();
}
}
if (MetaKeyKeyListener.isMetaTracker(buf, what)) {
mHighlightPathBogus = true;
if (ims != null && MetaKeyKeyListener.isSelectingMetaTracker(buf, what)) {
ims.mSelectionModeChanged = true;
}
if (Selection.getSelectionStart(buf) >= 0) {
if (ims == null || ims.mBatchEditNesting == 0) {
invalidateCursor();
} else {
ims.mCursorChanged = true;
}
}
}
if (what instanceof ParcelableSpan) {
// the current extract editor would be interested in it.
if (ims != null && ims.mExtractedTextRequest != null) {
if (ims.mBatchEditNesting != 0) {
if (oldStart >= 0) {
if (ims.mChangedStart > oldStart) {
ims.mChangedStart = oldStart;
}
if (ims.mChangedStart > oldEnd) {
ims.mChangedStart = oldEnd;
}
}
if (newStart >= 0) {
if (ims.mChangedStart > newStart) {
ims.mChangedStart = newStart;
}
if (ims.mChangedStart > newEnd) {
ims.mChangedStart = newEnd;
}
}
} else {
if (DEBUG_EXTRACT)
Log.v(LOG_TAG, "Span change outside of batch: " + oldStart + "-" + oldEnd + "," + newStart + "-" + newEnd + " " + what);
ims.mContentChanged = true;
}
}
}
if (mEditor != null && mEditor.mSpellChecker != null && newStart < 0 && what instanceof SpellCheckSpan) {
mEditor.mSpellChecker.onSpellCheckSpanRemoved((SpellCheckSpan) what);
}
}
use of android.text.style.CharacterStyle in project android_frameworks_base by ParanoidAndroid.
the class TextLine method handleRun.
/**
* Utility function for handling a unidirectional run. The run must not
* contain tabs or emoji but can contain styles.
*
*
* @param start the line-relative start of the run
* @param measureLimit the offset to measure to, between start and limit inclusive
* @param limit the limit of the run
* @param runIsRtl true if the run is right-to-left
* @param c the canvas, can be null
* @param x the end of the run closest to the leading margin
* @param top the top of the line
* @param y the baseline
* @param bottom the bottom of the line
* @param fmi receives metrics information, can be null
* @param needWidth true if the width is required
* @return the signed width of the run based on the run direction; only
* valid if needWidth is true
*/
private float handleRun(int start, int measureLimit, int limit, boolean runIsRtl, Canvas c, float x, int top, int y, int bottom, FontMetricsInt fmi, boolean needWidth) {
// Case of an empty line, make sure we update fmi according to mPaint
if (start == measureLimit) {
TextPaint wp = mWorkPaint;
wp.set(mPaint);
if (fmi != null) {
expandMetricsFromPaint(fmi, wp);
}
return 0f;
}
if (mSpanned == null) {
TextPaint wp = mWorkPaint;
wp.set(mPaint);
final int mlimit = measureLimit;
return handleText(wp, start, mlimit, start, limit, runIsRtl, c, x, top, y, bottom, fmi, needWidth || mlimit < measureLimit);
}
mMetricAffectingSpanSpanSet.init(mSpanned, mStart + start, mStart + limit);
mCharacterStyleSpanSet.init(mSpanned, mStart + start, mStart + limit);
// Shaping needs to take into account context up to metric boundaries,
// but rendering needs to take into account character style boundaries.
// So we iterate through metric runs to get metric bounds,
// then within each metric run iterate through character style runs
// for the run bounds.
final float originalX = x;
for (int i = start, inext; i < measureLimit; i = inext) {
TextPaint wp = mWorkPaint;
wp.set(mPaint);
inext = mMetricAffectingSpanSpanSet.getNextTransition(mStart + i, mStart + limit) - mStart;
int mlimit = Math.min(inext, measureLimit);
ReplacementSpan replacement = null;
for (int j = 0; j < mMetricAffectingSpanSpanSet.numberOfSpans; j++) {
// empty by construction. This special case in getSpans() explains the >= & <= tests
if ((mMetricAffectingSpanSpanSet.spanStarts[j] >= mStart + mlimit) || (mMetricAffectingSpanSpanSet.spanEnds[j] <= mStart + i))
continue;
MetricAffectingSpan span = mMetricAffectingSpanSpanSet.spans[j];
if (span instanceof ReplacementSpan) {
replacement = (ReplacementSpan) span;
} else {
// We might have a replacement that uses the draw
// state, otherwise measure state would suffice.
span.updateDrawState(wp);
}
}
if (replacement != null) {
x += handleReplacement(replacement, wp, i, mlimit, runIsRtl, c, x, top, y, bottom, fmi, needWidth || mlimit < measureLimit);
continue;
}
for (int j = i, jnext; j < mlimit; j = jnext) {
jnext = mCharacterStyleSpanSet.getNextTransition(mStart + j, mStart + mlimit) - mStart;
wp.set(mPaint);
for (int k = 0; k < mCharacterStyleSpanSet.numberOfSpans; k++) {
// Intentionally using >= and <= as explained above
if ((mCharacterStyleSpanSet.spanStarts[k] >= mStart + jnext) || (mCharacterStyleSpanSet.spanEnds[k] <= mStart + j))
continue;
CharacterStyle span = mCharacterStyleSpanSet.spans[k];
span.updateDrawState(wp);
}
x += handleText(wp, j, jnext, i, inext, runIsRtl, c, x, top, y, bottom, fmi, needWidth || jnext < measureLimit);
}
}
return x - originalX;
}
use of android.text.style.CharacterStyle in project android_frameworks_base by ParanoidAndroid.
the class TextView method spanChange.
/**
* Not private so it can be called from an inner class without going
* through a thunk.
*/
void spanChange(Spanned buf, Object what, int oldStart, int newStart, int oldEnd, int newEnd) {
// XXX Make the start and end move together if this ends up
// spending too much time invalidating.
boolean selChanged = false;
int newSelStart = -1, newSelEnd = -1;
final Editor.InputMethodState ims = mEditor == null ? null : mEditor.mInputMethodState;
if (what == Selection.SELECTION_END) {
selChanged = true;
newSelEnd = newStart;
if (oldStart >= 0 || newStart >= 0) {
invalidateCursor(Selection.getSelectionStart(buf), oldStart, newStart);
checkForResize();
registerForPreDraw();
if (mEditor != null)
mEditor.makeBlink();
}
}
if (what == Selection.SELECTION_START) {
selChanged = true;
newSelStart = newStart;
if (oldStart >= 0 || newStart >= 0) {
int end = Selection.getSelectionEnd(buf);
invalidateCursor(end, oldStart, newStart);
}
}
if (selChanged) {
mHighlightPathBogus = true;
if (mEditor != null && !isFocused())
mEditor.mSelectionMoved = true;
if ((buf.getSpanFlags(what) & Spanned.SPAN_INTERMEDIATE) == 0) {
if (newSelStart < 0) {
newSelStart = Selection.getSelectionStart(buf);
}
if (newSelEnd < 0) {
newSelEnd = Selection.getSelectionEnd(buf);
}
onSelectionChanged(newSelStart, newSelEnd);
}
}
if (what instanceof UpdateAppearance || what instanceof ParagraphStyle || what instanceof CharacterStyle) {
if (ims == null || ims.mBatchEditNesting == 0) {
invalidate();
mHighlightPathBogus = true;
checkForResize();
} else {
ims.mContentChanged = true;
}
if (mEditor != null) {
if (oldStart >= 0)
mEditor.invalidateTextDisplayList(mLayout, oldStart, oldEnd);
if (newStart >= 0)
mEditor.invalidateTextDisplayList(mLayout, newStart, newEnd);
}
}
if (MetaKeyKeyListener.isMetaTracker(buf, what)) {
mHighlightPathBogus = true;
if (ims != null && MetaKeyKeyListener.isSelectingMetaTracker(buf, what)) {
ims.mSelectionModeChanged = true;
}
if (Selection.getSelectionStart(buf) >= 0) {
if (ims == null || ims.mBatchEditNesting == 0) {
invalidateCursor();
} else {
ims.mCursorChanged = true;
}
}
}
if (what instanceof ParcelableSpan) {
// the current extract editor would be interested in it.
if (ims != null && ims.mExtractedTextRequest != null) {
if (ims.mBatchEditNesting != 0) {
if (oldStart >= 0) {
if (ims.mChangedStart > oldStart) {
ims.mChangedStart = oldStart;
}
if (ims.mChangedStart > oldEnd) {
ims.mChangedStart = oldEnd;
}
}
if (newStart >= 0) {
if (ims.mChangedStart > newStart) {
ims.mChangedStart = newStart;
}
if (ims.mChangedStart > newEnd) {
ims.mChangedStart = newEnd;
}
}
} else {
if (DEBUG_EXTRACT)
Log.v(LOG_TAG, "Span change outside of batch: " + oldStart + "-" + oldEnd + "," + newStart + "-" + newEnd + " " + what);
ims.mContentChanged = true;
}
}
}
if (mEditor != null && mEditor.mSpellChecker != null && newStart < 0 && what instanceof SpellCheckSpan) {
mEditor.mSpellChecker.onSpellCheckSpanRemoved((SpellCheckSpan) what);
}
}
Aggregations