private FixingResult addSpacesAroundSpansUntilFixed( SpannableStringBuilder builder, int widthMeasureSpec, int heightMeasureSpec) { Object[] spans = builder.getSpans(0, builder.length(), Object.class); List<Object> spansWithSpacesBefore = new ArrayList<Object>(spans.length); List<Object> spansWithSpacesAfter = new ArrayList<Object>(spans.length); for (Object span : spans) { int spanStart = builder.getSpanStart(span); if (isNotSpace(builder, spanStart - 1)) { builder.insert(spanStart, " "); spansWithSpacesBefore.add(span); } int spanEnd = builder.getSpanEnd(span); if (isNotSpace(builder, spanEnd)) { builder.insert(spanEnd, " "); spansWithSpacesAfter.add(span); } try { setTextAndMeasure(builder, widthMeasureSpec, heightMeasureSpec); return FixingResult.fixed(spansWithSpacesBefore, spansWithSpacesAfter); } catch (IndexOutOfBoundsException notFixed) { } } if (HtmlTextView.DEBUG) { Log.d(HtmlTextView.TAG, "Could not fix the Spanned by adding spaces around spans"); } return FixingResult.notFixed(); }
/** * 组合消息文本 * * @param name * @param body * @return */ public static SpannableStringBuilder parseFriendPostpan( String name, SpannableStringBuilder body) { SpannableStringBuilder sp = null; int start = 0; int end = 0; String mName = name + ":"; sp = body.insert(0, mName); // sp = new SpannableString(name + ":" + body); end = name.length(); // 设置用户名字体加粗、高亮 sp.setSpan( new StyleSpan(android.graphics.Typeface.BOLD), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); sp.setSpan( new ForegroundColorSpan(Color.parseColor("#2f548f")), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); sp.setSpan( new ForegroundColorSpan(Color.parseColor("#ff000000")), end, sp.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return sp; }
public void testFilter() { // Define the variables CharSequence source; SpannableStringBuilder dest; // Constructor to create a LengthFilter LengthFilter lengthFilter = new LengthFilter(10); InputFilter[] filters = {lengthFilter}; // filter() implicitly invoked. If the total length > filter length, the filter will // cut off the source CharSequence from beginning to fit the filter length. source = "abc"; dest = new SpannableStringBuilder("abcdefgh"); dest.setFilters(filters); dest.insert(1, source); String expectedString1 = "aabbcdefgh"; assertEquals(expectedString1, dest.toString()); dest.replace(5, 8, source); String expectedString2 = "aabbcabcgh"; assertEquals(expectedString2, dest.toString()); dest.delete(1, 3); String expectedString3 = "abcabcgh"; assertEquals(expectedString3, dest.toString()); // filter() explicitly invoked dest = new SpannableStringBuilder("abcdefgh"); CharSequence beforeFilterSource = "TestLengthFilter"; String expectedAfterFilter = "TestLength"; CharSequence actualAfterFilter = lengthFilter.filter( beforeFilterSource, 0, beforeFilterSource.length(), dest, 0, dest.length()); assertEquals(expectedAfterFilter, actualAfterFilter); }
@SuppressLint("WrongCall") private void removeUnneededSpaces( int widthMeasureSpec, int heightMeasureSpec, SpannableStringBuilder builder, FixingResult result) { for (Object span : result.spansWithSpacesAfter) { int spanEnd = builder.getSpanEnd(span); builder.delete(spanEnd, spanEnd + 1); try { setTextAndMeasure(builder, widthMeasureSpec, heightMeasureSpec); } catch (IndexOutOfBoundsException ignored) { builder.insert(spanEnd, " "); } } boolean needReset = true; for (Object span : result.spansWithSpacesBefore) { int spanStart = builder.getSpanStart(span); builder.delete(spanStart - 1, spanStart); try { setTextAndMeasure(builder, widthMeasureSpec, heightMeasureSpec); needReset = false; } catch (IndexOutOfBoundsException ignored) { needReset = true; int newSpanStart = spanStart - 1; builder.insert(newSpanStart, " "); } } if (needReset) { setText(builder); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } }
/** * 组合回复引用文本 * * @param name * @param body * @return */ public static SpannableStringBuilder parseQuoteSpan(String name, SpannableStringBuilder body) { String nName = "回复:" + name + "\n"; SpannableStringBuilder sp = body.insert(0, nName); // 设置用户名字体加粗、高亮 sp.setSpan( new StyleSpan(android.graphics.Typeface.BOLD), 3, nName.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); sp.setSpan( new ForegroundColorSpan(Color.parseColor("#0e5986")), 3, nName.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return sp; }
private void geckoReplaceText(int start, int oldEnd, CharSequence newText) { // Don't use replace() because Gingerbread has a bug where if the replaced text // has the same spans as the original text, the spans will end up being deleted mText.delete(start, oldEnd); mText.insert(start, newText); }