下面列出了怎么用android.text.style.AlignmentSpan的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Get the alignment of the specified paragraph, taking into account
* markup attached to it.
*/
public final Alignment getParagraphAlignment(int line) {
Alignment align = mAlignment;
if (mSpannedText) {
Spanned sp = (Spanned) mText;
AlignmentSpan[] spans = getParagraphSpans(sp, getLineStart(line),
getLineEnd(line),
AlignmentSpan.class);
int spanLength = spans.length;
if (spanLength > 0) {
align = spans[spanLength-1].getAlignment();
}
}
return align;
}
@Nullable
@Override
public Object getSpans(
@NonNull MarkwonConfiguration configuration,
@NonNull RenderProps renderProps,
@NonNull HtmlTag tag) {
final Layout.Alignment alignment;
// html attribute without value, <align center></align>
if (tag.attributes().containsKey("center")) {
alignment = Layout.Alignment.ALIGN_CENTER;
} else if (tag.attributes().containsKey("end")) {
alignment = Layout.Alignment.ALIGN_OPPOSITE;
} else {
// empty value or any other will make regular alignment
alignment = Layout.Alignment.ALIGN_NORMAL;
}
return new AlignmentSpan.Standard(alignment);
}
private void handleParagraph(int start, HtmlNode.HtmlAttr attr) {
if (attr == null) {
return;
}
setSpan(start, new StyleSpan(attr));
Layout.Alignment align;
if (attr.textAlign == HtmlNode.ALIGN_LEFT) {
align = Layout.Alignment.ALIGN_NORMAL;
} else if (attr.textAlign == HtmlNode.ALIGN_RIGHT) {
align = Layout.Alignment.ALIGN_OPPOSITE;
} else if (attr.textAlign == HtmlNode.ALIGN_CENTER) {
align = Layout.Alignment.ALIGN_CENTER;
} else {
align = null;
}
if (align != null) {
setSpan(start, position, new AlignmentSpan.Standard(align));
}
}
private static void encodeTextAlignmentByDiv(StringBuilder out, Spanned text, int option) {
int len = text.length();
int next;
for (int i = 0; i < len; i = next) {
next = text.nextSpanTransition(i, len, ParagraphStyle.class);
ParagraphStyle[] style = text.getSpans(i, next, ParagraphStyle.class);
String elements = " ";
boolean needDiv = false;
for(int j = 0; j < style.length; j++) {
if (style[j] instanceof AlignmentSpan) {
Layout.Alignment align =
((AlignmentSpan) style[j]).getAlignment();
needDiv = true;
if (align == Layout.Alignment.ALIGN_CENTER) {
elements = "align=\"center\" " + elements;
} else if (align == Layout.Alignment.ALIGN_OPPOSITE) {
elements = "align=\"right\" " + elements;
} else {
elements = "align=\"left\" " + elements;
}
}
}
if (needDiv) {
out.append("<div ").append(elements).append(">");
}
withinDiv(out, text, i, next, option);
if (needDiv) {
out.append("</div>");
}
}
}
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));
}
}
private static void withinHtml(StringBuilder out, Spanned text) {
int len = text.length();
int next;
for (int i = 0; i < text.length(); i = next) {
next = text.nextSpanTransition(i, len, ParagraphStyle.class);
ParagraphStyle[] style = text.getSpans(i, next, ParagraphStyle.class);
String elements = " ";
boolean needDiv = false;
for(int j = 0; j < style.length; j++) {
if (style[j] instanceof AlignmentSpan) {
Layout.Alignment align =
((AlignmentSpan) style[j]).getAlignment();
needDiv = true;
if (align == Layout.Alignment.ALIGN_CENTER) {
elements = "align=\"center\" " + elements;
} else if (align == Layout.Alignment.ALIGN_OPPOSITE) {
elements = "align=\"right\" " + elements;
} else {
elements = "align=\"left\" " + elements;
}
}
}
if (needDiv) {
out.append("<div ").append(elements).append(">");
}
withinDiv(out, text, i, next);
if (needDiv) {
out.append("</div>");
}
}
}
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));
}
}
private /* static */ void encodeTextAlignmentByDiv(StringBuilder out, Spanned text, int option) {
int len = text.length();
int next;
for (int i = 0; i < len; i = next) {
next = text.nextSpanTransition(i, len, ParagraphStyle.class);
ParagraphStyle[] style = text.getSpans(i, next, ParagraphStyle.class);
String elements = " ";
boolean needDiv = false;
for(int j = 0; j < style.length; j++) {
if (style[j] instanceof AlignmentSpan) {
Layout.Alignment align =
((AlignmentSpan) style[j]).getAlignment();
needDiv = true;
if (align == Layout.Alignment.ALIGN_CENTER) {
elements = "align=\"center\" " + elements;
} else if (align == Layout.Alignment.ALIGN_OPPOSITE) {
elements = "align=\"right\" " + elements;
} else {
elements = "align=\"left\" " + elements;
}
}
}
if (needDiv) {
out.append("<div ").append(elements).append(">");
}
withinDiv(out, text, i, next, option);
if (needDiv) {
out.append("</div>");
}
}
}
/**
* Show a toast
*/
public static void showToast(String content, Context context) {
Spannable centeredText = new SpannableString(content);
centeredText.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER),
0, content.length() - 1,
Spannable.SPAN_INCLUSIVE_INCLUSIVE);
Toast t = Toast.makeText(context,
centeredText,
Toast.LENGTH_SHORT);
t.setGravity(Gravity.BOTTOM, 0, (int) UIUtil.convertDpToPixel(100, context));
t.show();
}
private String paragraphToMarkDown(List<Object> mSpans, StringBuilder source) {
if (mSpans == null || mSpans.size() == 0) {
return source.toString();
}
String str = source.toString();
for (Object obj : mSpans) {
if (obj instanceof ReferSpan) {
str = formater.formatRefer(str);
} else if (obj instanceof AlignmentSpan) {
//markdown是不支持居中的!!!,后期考虑注释掉
// str = formater.formatCenter(str);
} else if (obj instanceof AbsoluteSizeSpan) {
AbsoluteSizeSpan sizeSpan = (AbsoluteSizeSpan) obj;
switch (sizeSpan.getSize()) {
case Const.T1_SIZE:
str = formater.formatH1(str);
break;
case Const.T2_SIZE:
str = formater.formatH2(str);
break;
case Const.T3_SIZE:
str = formater.formatH3(str);
break;
case Const.T4_SIZE:
str = formater.formatH4(str);
break;
}
}
}
return str;
}
@Test
public void align_start_should_add_only_one_span() {
spanBuilder.alignStart(paragraph)
.apply();
verify((SpanEZ) spanBuilder, times(1))
.addSpan(isA(TargetRange.class), isA(AlignmentSpan.class));
}
@Test
public void align_center_should_add_only_one_span() {
spanBuilder.alignCenter(paragraph)
.apply();
verify((SpanEZ) spanBuilder, times(1))
.addSpan(isA(TargetRange.class), isA(AlignmentSpan.class));
}
@Test
public void align_end_should_add_only_one_span() {
spanBuilder.alignEnd(paragraph)
.apply();
verify((SpanEZ) spanBuilder, times(1))
.addSpan(isA(TargetRange.class), isA(AlignmentSpan.class));
}
/**
* Create a task list which contains {@link SetSpanOperation}. The task list will be executed
* in other method.
* @param end the end character of the text.
* @return a task list which contains {@link SetSpanOperation}.
*/
private List<SetSpanOperation> createSetSpanOperation(int end, int spanFlag) {
List<SetSpanOperation> ops = new LinkedList<>();
int start = 0;
if (end >= start) {
if (mTextDecoration == WXTextDecoration.UNDERLINE || mTextDecoration == WXTextDecoration.LINETHROUGH) {
ops.add(new SetSpanOperation(start, end, new TextDecorationSpan(mTextDecoration), spanFlag));
}
if (mIsColorSet) {
ops.add(new SetSpanOperation(start, end,
new ForegroundColorSpan(mColor), spanFlag));
}
if (mFontSize != UNSET) {
ops.add(new SetSpanOperation(start, end, new AbsoluteSizeSpan(mFontSize), spanFlag));
}
if (mFontStyle != UNSET
|| mFontWeight != UNSET
|| mFontFamily != null) {
ops.add(new SetSpanOperation(start, end,
new WXCustomStyleSpan(mFontStyle, mFontWeight, mFontFamily),
spanFlag));
}
ops.add(new SetSpanOperation(start, end, new AlignmentSpan.Standard(mAlignment), spanFlag));
if (mLineHeight != UNSET) {
ops.add(new SetSpanOperation(start, end, new WXLineHeightSpan(mLineHeight), spanFlag));
}
}
return ops;
}
private static void encodeTextAlignmentByDiv(Context context, StringBuilder out, Spanned text, int option) {
int len = text.length();
int next;
for (int i = 0; i < len; i = next) {
next = text.nextSpanTransition(i, len, ParagraphStyle.class);
ParagraphStyle[] styles = text.getSpans(i, next, ParagraphStyle.class);
String elements = " ";
boolean needDiv = false;
for (ParagraphStyle style : styles) {
if (style instanceof AlignmentSpan) {
Layout.Alignment align =
((AlignmentSpan) style).getAlignment();
needDiv = true;
if (align == Layout.Alignment.ALIGN_CENTER) {
elements = "align=\"center\" " + elements;
} else if (align == Layout.Alignment.ALIGN_OPPOSITE) {
elements = "align=\"right\" " + elements;
} else {
elements = "align=\"left\" " + elements;
}
}
}
if (needDiv) {
out.append("<div ").append(elements).append(">");
}
withinDiv(context, out, text, i, next, option);
if (needDiv) {
out.append("</div>");
}
}
}
private static String getTextStyles(Spanned text, int start, int end,
boolean forceNoVerticalMargin, boolean includeTextAlign) {
String margin = null;
String textAlign = null;
if (forceNoVerticalMargin) {
margin = "margin-top:0; margin-bottom:0;";
}
if (includeTextAlign) {
final AlignmentSpan[] alignmentSpans = text.getSpans(start, end, AlignmentSpan.class);
// Only use the last AlignmentSpan with flag SPAN_PARAGRAPH
for (int i = alignmentSpans.length - 1; i >= 0; i--) {
AlignmentSpan s = alignmentSpans[i];
if ((text.getSpanFlags(s) & Spanned.SPAN_PARAGRAPH) == Spanned.SPAN_PARAGRAPH) {
final Layout.Alignment alignment = s.getAlignment();
if (alignment == Layout.Alignment.ALIGN_NORMAL) {
textAlign = "text-align:start;";
} else if (alignment == Layout.Alignment.ALIGN_CENTER) {
textAlign = "text-align:center;";
} else if (alignment == Layout.Alignment.ALIGN_OPPOSITE) {
textAlign = "text-align:end;";
}
break;
}
}
}
if (margin == null && textAlign == null) {
return "";
}
final StringBuilder style = new StringBuilder(" style=\"");
if (margin != null && textAlign != null) {
style.append(margin).append(" ").append(textAlign);
} else if (margin != null) {
style.append(margin);
} else if (textAlign != null) {
style.append(textAlign);
}
return style.append("\"").toString();
}
private void endBlockElement(String tag, 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(tag, text, a, new AlignmentSpan.Standard(a.mAlignment));
}
}
/**
* Create a task list which contains {@link SetSpanOperation}. The task list will be executed
* in other method.
* @param end the end character of the text.
* @return a task list which contains {@link SetSpanOperation}.
*/
private List<SetSpanOperation> createSetSpanOperation(int end, int spanFlag) {
List<SetSpanOperation> ops = new LinkedList<>();
int start = 0;
if (end >= start) {
if (mTextDecoration == WXTextDecoration.UNDERLINE) {
ops.add(new SetSpanOperation(start, end,
new UnderlineSpan(), spanFlag));
}
if (mTextDecoration == WXTextDecoration.LINETHROUGH) {
ops.add(new SetSpanOperation(start, end,
new StrikethroughSpan(), spanFlag));
}
if (mIsColorSet) {
ops.add(new SetSpanOperation(start, end,
new ForegroundColorSpan(mColor), spanFlag));
}
if (mFontSize != UNSET) {
ops.add(new SetSpanOperation(start, end, new AbsoluteSizeSpan(mFontSize), spanFlag));
}
if (mFontStyle != UNSET
|| mFontWeight != UNSET
|| mFontFamily != null) {
ops.add(new SetSpanOperation(start, end,
new WXCustomStyleSpan(mFontStyle, mFontWeight, mFontFamily),
spanFlag));
}
ops.add(new SetSpanOperation(start, end, new AlignmentSpan.Standard(mAlignment), spanFlag));
if (mLineHeight != UNSET) {
ops.add(new SetSpanOperation(start, end, new WXLineHeightSpan(mLineHeight), spanFlag));
}
}
return ops;
}
private void chartViewAdjusted() {
chartChangeTimestamp = System.currentTimeMillis();
long end = timeLastSGV == 0 ? chartChangeTimestamp - chartTimeOffset : timeLastSGV - chartTimeOffset;
long start = end - chartZoom * 60 * 60000L;
String t = String.format(getString(R.string.main_screen__value_hour_chart), chartZoom);
String m = String.format("\n%s %s",
FormatKit.getInstance().formatAsMonthName(start),
FormatKit.getInstance().formatAsDay(start)
);
String d = String.format("\n%s - %s",
FormatKit.getInstance().formatAsDayClock(start),
FormatKit.getInstance().formatAsDayClock(end)
);
SpannableStringBuilder ssb = new SpannableStringBuilder();
ssb.append(t);
ssb.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER), ssb.length() - t.length(), ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.setSpan(new StyleSpan(Typeface.BOLD), ssb.length() - t.length(), ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.append(m);
ssb.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER), ssb.length() - m.length(), ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.setSpan(new RelativeSizeSpan(0.75f), ssb.length() - m.length(), ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.append(d);
ssb.setSpan(new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER), ssb.length() - d.length(), ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.setSpan(new RelativeSizeSpan(0.85f), ssb.length() - d.length(), ssb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
toast = serveToast(ssb, toast, findViewById(R.id.view_sgv));
refreshDisplayChart();
}
private static void encodeTextAlignmentByDiv(StringBuilder out, Spanned text, int option) {
int len = text.length();
int next;
for (int i = 0; i < len; i = next) {
next = text.nextSpanTransition(i, len, ParagraphStyle.class);
ParagraphStyle[] style = text.getSpans(i, next, ParagraphStyle.class);
String elements = " ";
boolean needDiv = false;
for (int j = 0; j < style.length; j++) {
if (style[j] instanceof AlignmentSpan) {
Layout.Alignment align =
((AlignmentSpan) style[j]).getAlignment();
needDiv = true;
if (align == Layout.Alignment.ALIGN_CENTER) {
elements = "align=\"center\" " + elements;
} else if (align == Layout.Alignment.ALIGN_OPPOSITE) {
elements = "align=\"right\" " + elements;
} else {
elements = "align=\"left\" " + elements;
}
}
}
if (needDiv) {
out.append("<div ").append(elements).append(">");
}
withinDiv(out, text, i, next, option);
if (needDiv) {
out.append("</div>");
}
}
}
private static String getTextStyles(Spanned text, int start, int end,
boolean forceNoVerticalMargin, boolean includeTextAlign) {
String margin = null;
String textAlign = null;
if (forceNoVerticalMargin) {
margin = "margin-top:0; margin-bottom:0;";
}
if (includeTextAlign) {
final AlignmentSpan[] alignmentSpans = text.getSpans(start, end, AlignmentSpan.class);
// Only use the last AlignmentSpan with flag SPAN_PARAGRAPH
for (int i = alignmentSpans.length - 1; i >= 0; i--) {
AlignmentSpan s = alignmentSpans[i];
if ((text.getSpanFlags(s) & Spanned.SPAN_PARAGRAPH) == Spanned.SPAN_PARAGRAPH) {
final Layout.Alignment alignment = s.getAlignment();
if (alignment == Layout.Alignment.ALIGN_NORMAL) {
textAlign = "text-align:start;";
} else if (alignment == Layout.Alignment.ALIGN_CENTER) {
textAlign = "text-align:center;";
} else if (alignment == Layout.Alignment.ALIGN_OPPOSITE) {
textAlign = "text-align:end;";
}
break;
}
}
}
if (margin == null && textAlign == null) {
return "";
}
final StringBuilder style = new StringBuilder(" style=\"");
if (margin != null && textAlign != null) {
style.append(margin).append(" ").append(textAlign);
} else if (margin != null) {
style.append(margin);
} else if (textAlign != null) {
style.append(textAlign);
}
return style.append("\"").toString();
}
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));
}
}
public TextDecorator alignText(final Layout.Alignment alignment, final String... texts) {
int index;
for (String text : texts) {
if (content.contains(text)) {
index = content.indexOf(text);
decoratedContent.setSpan(new AlignmentSpan.Standard(alignment), index, index + text.length(), flags);
}
}
return this;
}
float computeFlushFactor() {
Layout.Alignment alignment = null;
// Get the top most alignment.
for (int i = paragraphSpans.length - 1; i >= 0; i--) {
if (paragraphSpans[i] instanceof AlignmentSpan) {
alignment = ((AlignmentSpan) paragraphSpans[i]).getAlignment();
break;
}
}
return getFlushFactor(alignment, baseLevel);
}
/**
* Create a task list which contains {@link SetSpanOperation}. The task list will be executed
* in other method.
* @param end the end character of the text.
* @return a task list which contains {@link SetSpanOperation}.
*/
private List<SetSpanOperation> createSetSpanOperation(int end) {
List<SetSpanOperation> ops = new LinkedList<>();
int start = 0;
if (end >= start) {
if (mTextDecoration == WXTextDecoration.UNDERLINE) {
ops.add(new SetSpanOperation(start, end,
new UnderlineSpan()));
}
if (mTextDecoration == WXTextDecoration.LINETHROUGH) {
ops.add(new SetSpanOperation(start, end,
new StrikethroughSpan()));
}
if (mIsColorSet) {
ops.add(new SetSpanOperation(start, end,
new ForegroundColorSpan(mColor)));
}
if (mFontSize != UNSET) {
ops.add(new SetSpanOperation(start, end, new AbsoluteSizeSpan(mFontSize)));
}
if (mFontStyle != UNSET
|| mFontWeight != UNSET
|| mFontFamily != null) {
ops.add(new SetSpanOperation(start, end,
new WXCustomStyleSpan(mFontStyle, mFontWeight, mFontFamily)));
}
ops.add(new SetSpanOperation(start, end, new AlignmentSpan.Standard(mAlignment)));
if(mLineHeight !=UNSET) {
ops.add(new SetSpanOperation(start, end, new WXLineHeightSpan(mLineHeight)));
}
}
return ops;
}
private void handleBlockTag(boolean isStart, int type, int start, HtmlNode.HtmlAttr attr) {
if (position <= 0) {
return;
}
if (spannedBuilder.charAt(position - 1) != '\n') {
spannedBuilder.append('\n');
position++;
}
//结束block 标签
if (!isStart && attr != null) {
Layout.Alignment align;
if (attr.align == HtmlNode.ALIGN_LEFT) {
align = Layout.Alignment.ALIGN_NORMAL;
} else if (attr.align == HtmlNode.ALIGN_RIGHT) {
align = Layout.Alignment.ALIGN_OPPOSITE;
} else if (attr.align == HtmlNode.ALIGN_CENTER) {
align = Layout.Alignment.ALIGN_CENTER;
} else {
align = null;
}
if (align != null) {
setSpan(start, position, new AlignmentSpan.Standard(align));
}
}
}
private static void withinHtml(StringBuilder out, Spanned text) {
int len = text.length();
int next;
for (int i = 0; i < text.length(); i = next) {
next = text.nextSpanTransition(i, len, ParagraphStyle.class);
ParagraphStyle[] style = text.getSpans(i, next, ParagraphStyle.class);
String elements = " ";
boolean needDiv = false;
for(int j = 0; j < style.length; j++) {
if (style[j] instanceof AlignmentSpan) {
Layout.Alignment align =
((AlignmentSpan) style[j]).getAlignment();
needDiv = true;
if (align == Layout.Alignment.ALIGN_CENTER) {
elements = "align=\"center\" " + elements;
} else if (align == Layout.Alignment.ALIGN_OPPOSITE) {
elements = "align=\"right\" " + elements;
} else {
elements = "align=\"left\" " + elements;
}
}
}
if (needDiv) {
out.append("<div ").append(elements).append(">");
}
withinDiv(out, text, i, next);
if (needDiv) {
out.append("</div>");
}
}
}
private static void withinHtml(StringBuilder out, Spanned text) {
int len = text.length();
int next;
for (int i = 0; i < text.length(); i = next) {
next = text.nextSpanTransition(i, len, ParagraphStyle.class);
ParagraphStyle[] style = text.getSpans(i, next, ParagraphStyle.class);
String elements = " ";
boolean needDiv = false;
for(int j = 0; j < style.length; j++) {
if (style[j] instanceof AlignmentSpan) {
Layout.Alignment align =
((AlignmentSpan) style[j]).getAlignment();
needDiv = true;
if (align == Layout.Alignment.ALIGN_CENTER) {
elements = "align=\"center\" " + elements;
} else if (align == Layout.Alignment.ALIGN_OPPOSITE) {
elements = "align=\"right\" " + elements;
} else {
elements = "align=\"left\" " + elements;
}
}
}
if (needDiv) {
out.append("<div ").append(elements).append(">");
}
withinDiv(out, text, i, next);
if (needDiv) {
out.append("</div>");
}
}
}
private static void withinHtml(StringBuilder out, Spanned text ) {
int len = text.length();
int next;
for (int i = 0; i < text.length(); i = next) {
next = text.nextSpanTransition(i, len, ParagraphStyle.class);
ParagraphStyle[] style = text.getSpans(i, next,
ParagraphStyle.class);
String elements = " ";
boolean needDiv = false;
for (int j = 0; j < style.length; j++) {
if (style[j] instanceof AlignmentSpan) {
Layout.Alignment align = ((AlignmentSpan) style[j])
.getAlignment();
needDiv = true;
if (align == Layout.Alignment.ALIGN_CENTER) {
elements = "align=\"center\" " + elements;
} else if (align == Layout.Alignment.ALIGN_OPPOSITE) {
elements = "align=\"right\" " + elements;
} else {
elements = "align=\"left\" " + elements;
}
}
}
if (needDiv) {
out.append("<div " + elements + ">");
}
withinDiv(out, text, i, next);
if (needDiv) {
out.append("</div>");
}
}
}
private void appendText(CharSequence text, Layout.Alignment align) {
if (text == null || text.toString().trim().length() == 0) {
return;
}
AlignmentSpan span = new AlignmentSpan.Standard(align);
SpannableString spannableString = new SpannableString(text);
spannableString.setSpan(span, 0, text.length(), 0);
if (textView.length() > 0) {
textView.append("\n\n");
}
textView.append(spannableString);
}