private FixingResult addSpacesAroundSpansUntilFixed(SpannableStringBuilder builder, int widthMeasureSpec, int heightMeasureSpec) { Object[] spans = builder.getSpans(0, builder.length(), Object.class); List<Object> spansWithSpacesBefore = new ArrayList<>(spans.length); List<Object> spansWithSpacesAfter = new ArrayList<>(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 ignored) { } } if (HtmlTextView.DEBUG) { Log.d(HtmlTextView.TAG, "Could not fix the Spanned by adding spaces around spans"); } return FixingResult.notFixed(); }
@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); } }
public static Spannable applyKerning(CharSequence src, float kerning) { if (src == null) return null; final int srcLength = src.length(); if (srcLength < 2) return src instanceof Spannable ? (Spannable)src : new SpannableString(src); final String nonBreakingSpace = "\u00A0"; final SpannableStringBuilder builder = src instanceof SpannableStringBuilder ? (SpannableStringBuilder)src : new SpannableStringBuilder(src); for (int i = src.length() - 1; i >= 1; i--) { builder.insert(i, nonBreakingSpace); builder.setSpan(new ScaleXSpan(kerning), i, i + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } return builder; }
@Override public SpannableStringBuilder insert(int where, CharSequence tb) { super.insert(where, tb); return this; }
@Override public SpannableStringBuilder insert(int where, CharSequence tb, int start, int end) { super.insert(where, tb, start, end); return this; }
CharSequence firstPart = "First Part"; CharSequence thirdPart = "Third Part"; SpannableStringBuilder middlePart = new SpannableStringBuilder("Middle Part"); int spacing = 2; final String nonBreakingSpace = "\u00A0"; for (int i = middlePart.length() - 1; i >= 1; i--){ middlePart.insert(i, nonBreakingSpace); middlePart.setSpan(new ScaleXSpan(spacing), i, i + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } ((TextView) rootView.findViewById(R.id.text_view)).setText(TextUtils.concat(firstPart, " ", middlePart, " ", thirdPart));
private void formatLinks(SpannableStringBuilder titleSpan) { Matcher matcher = urlPattern.matcher(titleSpan); while(matcher.find()) { titleSpan.delete(matcher.start(), matcher.end()); titleSpan.insert(matcher.start(), matcher.group(1)); titleSpan.setSpan(new ForegroundColorSpan(Style.blue), matcher.start(), matcher.start() + matcher.group(1).length(), 0); matcher = urlPattern.matcher(titleSpan); } }
private static MDBaseListSpan setOrderSpan(int nested, int start, @NonNull String line, @NonNull SpannableStringBuilder ssb, int number, int originalNumber) { ssb.delete(start, start + nested * SyntaxKey.KEY_LIST_HEADER.length() + String.valueOf(originalNumber).length()); ssb.insert(start, String.valueOf(number)); MDOrderListSpan mdOrderListSpan = new MDOrderListSpan(10, nested, number); ssb.setSpan(mdOrderListSpan, start, start + line.length() - (nested * SyntaxKey.KEY_LIST_HEADER.length() + String.valueOf(originalNumber).length()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); return mdOrderListSpan; }
/** * set key number * * @param nested the nested number * @param start start position * @param line the content * @param ssb the content * @param number the key number * @param originalNumber the original number */ private void setSSB(int nested, int start, @NonNull String line, @NonNull SpannableStringBuilder ssb, int number, int originalNumber) { ssb.delete(start, start + nested * SyntaxKey.KEY_LIST_HEADER.length() + String.valueOf(originalNumber).length()); ssb.insert(start, String.valueOf(number)); ssb.setSpan(new MDOrderListSpan(10, nested, number), start, start + line.length() - (nested * SyntaxKey.KEY_LIST_HEADER.length() + String.valueOf(originalNumber).length()), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); }
private void handleBlockquote(int start) { spannedBuilder.insert(start, "“ "); spannedBuilder.append("”"); position += 3; setSpan(start, new Quote()); }
public void insertIcon(String name) { String curString = getText().toString(); if ((curString.length() + name.length()) > maxLength) { return; } Drawable drawable = ContextCompat.getDrawable(mContext, ParseIconResId(name)); if (drawable == null) return; drawable.setBounds(0, 0, size, size);//这里设置图片的大小 ImageSpan imageSpan = new ImageSpan(drawable); SpannableString spannableString = new SpannableString(name); spannableString.setSpan(imageSpan, 0, spannableString.length(), SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE); int index = Math.max(getSelectionStart(), 0); SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(getText()); spannableStringBuilder.insert(index, spannableString); setText(spannableStringBuilder); setSelection(index + spannableString.length()); }
public CharSequence getHeading(Printrequest printRequest) { String name = printRequest.sentbyname; String permission; if (printRequest.mediaobject.permission != null && !printRequest.mediaobject.permission.equalsIgnoreCase("public")) { permission = printRequest.mediaobject.permission; } else { permission = ""; } String photoHeading = mContext.getString(R.string.photo_heading); SpannableStringBuilder builder = new SpannableStringBuilder(photoHeading); int pos = builder.toString().indexOf("%s"); builder.replace(pos, pos+2, getStyledName(name)); pos = builder.toString().indexOf("%s"); builder.replace(pos, pos+2, getStyledItalic(permission)); pos = builder.toString().indexOf("%s"); if (printRequest.mediaobject.hyperphoto != null) { builder.replace(pos, pos+2, getStyledItalic(mContext.getString(R.string.hyperphoto))); builder.insert(pos, " "); } else { builder.replace(pos, pos+2, mContext.getString(R.string.photo)); builder.insert(pos, " "); } return builder; }
ssBuilder.removeSpan(span); if (span.getStyle() == Typeface.BOLD) { ssBuilder.insert(start, "<b>"); ssBuilder.insert(end + 3, "</b>"); } else if (span.getStyle() == Typeface.ITALIC) { ssBuilder.insert(start, "<i>"); ssBuilder.insert(end + 3, "</i>"); end = ssBuilder.getSpanEnd(span); ssBuilder.removeSpan(span); ssBuilder.insert(start, "<u>"); ssBuilder.insert(end + 3, "</u>");
int lineHeight = mLayout.getLineBottom(line) - mLayout.getLineTop(line); mText.insert(offsetStart, " ");
index--; spannableStringBuilder.insert(index, spannableString); GifTextUtil.setTextWithReuseDrawable(this, spannableStringBuilder, true); setSelection(index + spannableString.length());