下面列出了android.text.SpannableStringBuilder#getSpanStart ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static SpannableStringBuilder addNumbers(Spanned htmlSpanned, int numberFrom, int sp) {
int listItemCount = numberFrom-1;
SpannableStringBuilder spannableBuilder = new SpannableStringBuilder(htmlSpanned);
BulletSpan[] spans = spannableBuilder.getSpans(0, spannableBuilder.length(), BulletSpan.class);
if (spans != null) {
for (BulletSpan span : spans) {
int start = spannableBuilder.getSpanStart(span);
int end = spannableBuilder.getSpanEnd(span);
spannableBuilder.removeSpan(span);
++listItemCount;
spannableBuilder.insert(start, listItemCount + ". ");
spannableBuilder.setSpan(new LeadingMarginSpan.Standard(0, sip(sp)), start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
return spannableBuilder;
}
private static <T> void end(SpannableStringBuilder text, Class<T> kind, Object repl) {
int len = text.length();
T obj = getLast(text, kind);
int where = text.getSpanStart(obj);
text.removeSpan(obj);
Object[] nestSpans = text.getSpans(where, len, Object.class);
List<NestSpanInfo> spans = new ArrayList<>();
for (Object nestSpan : nestSpans) {
int spanStart = text.getSpanStart(nestSpan);
int spanEnd = text.getSpanEnd(nestSpan);
int spanFlags = text.getSpanFlags(nestSpan);
text.removeSpan(nestSpan);
spans.add(new NestSpanInfo(nestSpan, spanStart, spanEnd, spanFlags));
}
if (where != len) {
text.setSpan(repl, where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
//reorder spans
for (NestSpanInfo span : spans) {
text.setSpan(span.span, span.start, span.end, span.flag);
}
}
private static void endMultiple(SpannableStringBuilder text, Class kind,
Object[] replArray) {
int len = text.length();
Object obj = getLast(text, kind);
int where = text.getSpanStart(obj);
text.removeSpan(obj);
if (where != len) {
for (Object repl : replArray) {
text.setSpan(repl, where, len,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
private static void endHeader(SpannableStringBuilder text) {
int len = text.length();
Object obj = getLast(text, Header.class);
int where = text.getSpanStart(obj);
text.removeSpan(obj);
// Back off not to change only the text, not the blank line.
while (len > where && text.charAt(len - 1) == '\n') {
len--;
}
if (where != len) {
Header h = (Header) obj;
text.setSpan(new RelativeSizeSpan(HEADER_SIZES[h.mLevel]),
where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
text.setSpan(new StyleSpan(Typeface.BOLD),
where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
private void onBuiltinServerSelected(int i) {
description.setText(descriptions[i]);
// Update website text with a link pointing to the correct website.
// The string resource contains a dummy hyperlink that must be replaced with a new link to
// the correct destination.
CharSequence template = getResources().getText(R.string.server_choice_website_notice);
SpannableStringBuilder websiteMessage = new SpannableStringBuilder(template);
// Trim leading whitespace introduced by indentation in strings.xml.
while (Character.isWhitespace(websiteMessage.charAt(0))) {
websiteMessage.delete(0, 1);
}
// Replace hyperlink with a new link for the current URL.
URLSpan templateLink =
websiteMessage.getSpans(0, websiteMessage.length(), URLSpan.class)[0];
int linkStart = websiteMessage.getSpanStart(templateLink);
int linkEnd = websiteMessage.getSpanEnd(templateLink);
websiteMessage.removeSpan(templateLink);
websiteMessage.setSpan(new URLSpan(websiteLinks[i]), linkStart, linkEnd, 0);
serverWebsite.setText(websiteMessage);
}
private static void endHeader(SpannableStringBuilder text) {
int len = text.length();
Object obj = getLast(text, Header.class);
int where = text.getSpanStart(obj);
text.removeSpan(obj);
// Back off not to change only the text, not the blank line.
while (len > where && text.charAt(len - 1) == '\n') {
len--;
}
if (where != len) {
Header h = (Header) obj;
text.setSpan(new RelativeSizeSpan(HEADER_SIZES[h.mLevel]),
where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
text.setSpan(new StyleSpan(Typeface.BOLD),
where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
public static void setHtmlWithLinkClickHandler(TextView tv, String html,
Action1<String> linkClickHandler) {
CharSequence sequence = Html.fromHtml(html);
SpannableStringBuilder strBuilder = new SpannableStringBuilder(sequence);
URLSpan[] urls = strBuilder.getSpans(0, sequence.length(), URLSpan.class);
for (URLSpan span : urls) {
int start = strBuilder.getSpanStart(span);
int end = strBuilder.getSpanEnd(span);
int flags = strBuilder.getSpanFlags(span);
ClickableSpan clickable = new ClickableSpan() {
public void onClick(View view) {
linkClickHandler.call(span.getURL());
}
};
strBuilder.setSpan(clickable, start, end, flags);
strBuilder.removeSpan(span);
}
tv.setText(strBuilder);
tv.setMovementMethod(LinkMovementMethod.getInstance());
}
private void findSubscriptions(String[] subscriptions) {
char[] buf = null;
SpannableStringBuilder spanned = (SpannableStringBuilder) spannedComment;
for (String subscription : subscriptions) {
if (!referencesTo.contains(subscription)) continue;
ClickableURLSpan[] spans = spanned.getSpans(0, spanned.length(), ClickableURLSpan.class);
if (spans == null || spans.length == 0) continue;
char[] search = (">>" + subscription).toCharArray();
if (buf == null || buf.length != search.length) buf = new char[search.length];
for (ClickableURLSpan span : spans) {
int startIndex = spanned.getSpanStart(span);
if (startIndex + buf.length > spanned.length()) continue;
spanned.getChars(startIndex, startIndex + buf.length, buf, 0);
if (Arrays.equals(search, buf)) {
spanned.setSpan(new SubscriptionSpan(themeColors.subscriptionBackground),
startIndex, startIndex + buf.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
}
@Override
public void onResourceReady(Bitmap bitmap, GlideAnimation<? super Bitmap> glideAnimation) {
TextView tv = textView.get();
if (tv != null) {
BitmapDrawable bitmapDrawable = new BitmapDrawable(tv.getResources(), bitmap);
// image span doesn't handle scaling so we manually set bounds
if (bitmap.getWidth() > tv.getWidth()) {
float aspectRatio = (float) bitmap.getHeight() / (float) bitmap.getWidth();
bitmapDrawable.setBounds(0, 0, tv.getWidth(), (int) (aspectRatio * tv.getWidth()));
} else {
bitmapDrawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
}
ImageSpan span = new ImageSpan(bitmapDrawable);
// add the image span and remove our marker
SpannableStringBuilder ssb = new SpannableStringBuilder(tv.getText());
int start = ssb.getSpanStart(loadingSpan);
int end = ssb.getSpanEnd(loadingSpan);
if (start >= 0 && end >= 0) {
ssb.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
ssb.removeSpan(loadingSpan);
// animate the change
TransitionManager.beginDelayedTransition((ViewGroup) tv.getParent());
tv.setText(ssb);
}
}
private void setLinkClickable(final SpannableStringBuilder clickableHtmlBuilder,
final URLSpan urlSpan) {
int start = clickableHtmlBuilder.getSpanStart(urlSpan);
int end = clickableHtmlBuilder.getSpanEnd(urlSpan);
int flags = clickableHtmlBuilder.getSpanFlags(urlSpan);
clickableHtmlBuilder.setSpan(new ClickableSpan() {
public void onClick(View view) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(urlSpan.getURL()));
context.startActivity(intent);
} catch (Throwable e) {
e.printStackTrace();
}
}
}, start, end, flags);
}
/**
* An extension to {@link HtmlUtils#parseHtml(String, ColorStateList, int)} which adds Dribbble
* specific behaviour.
*/
public static Spanned parseDribbbleHtml(
String input,
ColorStateList linkTextColor,
@ColorInt int linkHighlightColor) {
SpannableStringBuilder ssb = HtmlUtils.parseHtml(input, linkTextColor, linkHighlightColor);
TouchableUrlSpan[] urlSpans = ssb.getSpans(0, ssb.length(), TouchableUrlSpan.class);
for (TouchableUrlSpan urlSpan : urlSpans) {
int start = ssb.getSpanStart(urlSpan);
if (ssb.subSequence(start, start + 1).toString().equals("@")) {
int end = ssb.getSpanEnd(urlSpan);
ssb.removeSpan(urlSpan);
HttpUrl url = HttpUrl.parse(urlSpan.getURL());
long playerId = -1l;
String playerUsername = null;
try {
playerId = Long.parseLong(url.pathSegments().get(0));
} catch (NumberFormatException nfe) {
playerUsername = url.pathSegments().get(0);
}
ssb.setSpan(new PlayerSpan(urlSpan.getURL(),
ssb.subSequence(start + 1, end).toString(),
playerId,
playerUsername,
linkTextColor,
linkHighlightColor),
start,
end,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return ssb;
}
private static void endFont(SpannableStringBuilder text) {
int len = text.length();
Object obj = getLast(text, Font.class);
int where = text.getSpanStart(obj);
text.removeSpan(obj);
if (where != len) {
Font f = (Font) obj;
if (!TextUtils.isEmpty(f.mColor)) {
if (f.mColor.startsWith("@")) {
Resources res = Resources.getSystem();
String name = f.mColor.substring(1);
int colorRes = res.getIdentifier(name, "color", "android");
text.setSpan(new TextAppearanceSpan(null, 0, 0, ColorStateList.valueOf(res.getColor(colorRes)), null),
where, len,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
try {
int c = getHtmlColor(f.mColor);
text.setSpan(new ForegroundColorSpan(c | 0xFF000000),
where, len,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} catch (IllegalArgumentException e) {
// Ignore
}
}
}
if (f.mFace != null) {
text.setSpan(new TypefaceSpan(f.mFace), where, len,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
private static void endA(SpannableStringBuilder text) {
int len = text.length();
Object obj = getLast(text, Href.class);
int where = text.getSpanStart(obj);
text.removeSpan(obj);
if (where != len) {
Href h = (Href) obj;
if (h.mHref != null) {
text.setSpan(new URLSpan(h.mHref), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
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 (BuildConfig.DEBUG) {
Log.d(HtmlTextView.TAG, "Could not fix the Spanned by adding spaces around spans");
}
return FixingResult.notFixed();
}
private void makeLinkClickable(SpannableStringBuilder strBuilder, final URLSpan span, Runnable runnable) {
int start = strBuilder.getSpanStart(span);
int end = strBuilder.getSpanEnd(span);
int flags = strBuilder.getSpanFlags(span);
ClickableSpan clickable = new ClickableSpan() {
public void onClick(View view) {
runnable.run();
}
};
strBuilder.setSpan(clickable, start, end, flags);
strBuilder.removeSpan(span);
}
public static ClickableURLSpan replaceURLSpan(SpannableStringBuilder builder, URLSpan span, int color) {
int start = builder.getSpanStart(span);
int end = builder.getSpanEnd(span);
String url = span.getURL();
builder.removeSpan(span);
ClickableURLSpan newSpan = new ClickableURLSpan(url);
builder.setSpan(newSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.setSpan(new ForegroundColorSpan(color), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return newSpan;
}
private boolean checkDuplicateSpan(SpannableStringBuilder text, int where, Class<?> kind) {
Object[] spans = text.getSpans(where, where, kind);
if (spans != null && spans.length > 0) {
for (int i = 0; i < spans.length; i++) {
if (text.getSpanStart(spans[i]) == where) {
return true;
}
}
}
return false;
}
void swapIn(SpannableStringBuilder builder) {
int start = builder.getSpanStart(this);
int end = builder.getSpanEnd(this);
builder.removeSpan(this);
if (start >= 0 && end > start && end <= builder.length()) {
builder.setSpan(mSpan, start, end, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
}
}
private static void endStreamA(SpannableStringBuilder text) {
int len = text.length();
Object obj = getLast(text, Href.class);
int where = text.getSpanStart(obj);
text.removeSpan(obj);
if (where != len) {
Href h = (Href) obj;
if (h != null && h.mHref != null) {
text.setSpan(new StreamSpan(h.mHref, 0xFF0088cc), where, len,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
private static void end(SpannableStringBuilder text, Class kind,
Object repl) {
int len = text.length();
Object obj = getLast(text, kind);
int where = text.getSpanStart(obj);
text.removeSpan(obj);
if (where != len) {
text.setSpan(repl, where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}