下面列出了android.text.SpannableStringBuilder#toString ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
protected RNSetGradientSpanOperation createSpan(
SpannableStringBuilder builder,
int start,
int end,
float maxWidth,
float maxHeight,
Layout layout
) {
RNLinearTextGradientSpan span = new RNLinearTextGradientSpan(
mLocations,
mColors,
mStart,
mEnd,
mUseViewFrame,
layout,
start,
end,
maxWidth,
maxHeight,
builder.toString()
);
return new RNSetGradientSpanOperation(start, end, span);
}
@Override
protected String getAccessibilityContentDescription(@NonNull final Context context) {
final SpannableStringBuilder builder = new SpannableStringBuilder();
final PayerCost currentInstallment = getCurrent();
final String money = context.getResources().getString(R.string.px_money);
builder
.append(currentInstallment.getInstallments().toString())
.append(TextUtil.SPACE)
.append(context.getResources().getString(R.string.px_date_divider))
.append(TextUtil.SPACE)
.append(currentInstallment.getInstallmentAmount().toString())
.append(TextUtil.SPACE)
.append(money)
.append(TextUtil.SPACE)
.append(hasAmountDescriptor() ? currentInstallment.getTotalAmount().floatValue() + money : TextUtil.EMPTY)
.append(hasInterestFree() ? interestFree.getInstallmentRow().getMessage() : TextUtil.EMPTY);
updateCFTSpannable(builder, context);
updateInstallmentsInfo(builder, context);
return builder.toString();
}
@Override
protected String getAccessibilityContentDescription() {
final SpannableStringBuilder builder = new SpannableStringBuilder();
builder
.append(model.paymentMethodId)
.append(TextUtil.SPACE)
.append(model.getIssuerName())
.append(TextUtil.SPACE)
.append(model.getDescription())
.append(TextUtil.SPACE)
.append(getString(R.string.px_date_divider))
.append(TextUtil.SPACE)
.append(model.card.getName());
return builder.toString();
}
public static SpannableStringBuilder trimSpannable(SpannableStringBuilder spannable) {
checkNotNull(spannable);
int trimStart = 0;
int trimEnd = 0;
String text = spannable.toString();
while (text.length() > 0 && text.startsWith("\n")) {
text = text.substring(1);
trimStart += 1;
}
while (text.length() > 0 && text.endsWith("\n")) {
text = text.substring(0, text.length() - 1);
trimEnd += 1;
}
return spannable.delete(0, trimStart)
.delete(spannable.length() - trimEnd, spannable.length());
}
String getCopyReadyComment(CharSequence text, int start, int end) {
if (text instanceof Spanned) {
SpannableStringBuilder builder = new SpannableStringBuilder(text.subSequence(start, end));
LinkSuffixSpan[] spans = builder.getSpans(0, builder.length(), LinkSuffixSpan.class);
if (spans != null && spans.length > 0) {
for (LinkSuffixSpan span : spans) {
int spanStart = builder.getSpanStart(span);
int spanEnd = builder.getSpanEnd(span);
builder.delete(spanStart, spanEnd);
}
}
return builder.toString();
} else {
return text.subSequence(start, end).toString();
}
}
private static String getTextWithPasswords(CharSequence seq) {
SpannableStringBuilder lstr = new SpannableStringBuilder(seq);
for (PasswordSpan span : lstr.getSpans(0, lstr.length(), PasswordSpan.class)) {
lstr.replace(lstr.getSpanStart(span), lstr.getSpanEnd(span), span.mPassword);
lstr.removeSpan(span);
}
return lstr.toString();
}
private String getRealText(boolean saved) {
if (saved && mMode == MODE_NONE) {
return null;
}
Editable editable = getText();
if (editable == null || editable.length() == 0) {
return "";
}
SpannableStringBuilder value = new SpannableStringBuilder(editable);
IPlaceholderSpan[] spans;
if (mMode == MODE_NONE) {
spans = EMPTY_SPANS;
} else if (mMode < MODE_MASK) {
spans =
value.getSpans(
0,
Math.min(value.length(), mHolders[mHolders.length - 1].index),
IPlaceholderSpan.class);
} else {
spans =
value.getSpans(
0,
Math.min(value.length(), mFormatStyle.length()),
IPlaceholderSpan.class);
if (spans.length == mFormatStyle.length()) {
return "";
}
}
if (spans.length == 0) {
if (saved) {
value.clear();
return null;
}
} else {
clearNonEmptySpans(value, spans, false);
}
final String realText = value.toString();
value.clear();
return realText;
}
@Override
protected String getAccessibilityContentDescription(@NonNull final Context context) {
final SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(getCurrent().getInstallmentAmount().toString())
.append(TextUtil.SPACE)
.append(context.getResources().getString(R.string.px_money));
return builder.toString();
}
/**
* 此操作是异步的,注意
* @param builder 包含公式的文本,以SpannableStringBuilder身份传入
*/
private void retrieveOnlineImg(final SpannableStringBuilder builder) {
String text = builder.toString();
mFormulaList = getAllFormulas(text);
showPlaceHolder(builder);
retrieveFormulaOnlineImg(builder, 0);
}
/**
* Retrieves the aggregate text from all {@link FeedbackFragment}s.
*
* @return all text contained by this item, or {@code null} if no fragments exist.
*/
public @Nullable CharSequence getAggregateText() {
if (mFragments.size() == 0) {
return null;
} else if (mFragments.size() == 1) {
return mFragments.get(0).getText();
}
final SpannableStringBuilder sb = new SpannableStringBuilder();
for (FeedbackFragment fragment : mFragments) {
StringBuilderUtils.appendWithSeparator(sb, fragment.getText());
}
return sb.toString();
}
private static CharSequence render(SpannableStringBuilder spannableStringBuilder, ArrayList<IconicFontEngine> engines) {
int caret = 0;
List<Pair<Integer, IconicFontEngine>> positions = new ArrayList<>();
while (true) {
StringBuilder text = new StringBuilder(spannableStringBuilder.toString());
int startBracketIndex = text.indexOf("{", caret);
int endBracketIndex = text.indexOf("}", startBracketIndex + 1);
if (startBracketIndex == -1 || endBracketIndex == -1) { break; }
String iconString = text.substring(startBracketIndex + 1, endBracketIndex);
boolean found = false;
for (IconicFontEngine engine : engines) {
Character fontChar = engine.getIconicFontMap().get(iconString);
if (fontChar != null) {
spannableStringBuilder.replace(startBracketIndex, endBracketIndex + 1, String.valueOf(fontChar));
positions.add(new Pair<>(startBracketIndex, engine));
caret = startBracketIndex + 1;
found = true;
break;
}
}
if (!found) {
Log.w(TAG, "{" + iconString + "} not fount in fontMaps");
caret = endBracketIndex + 1;
}
}
for (Pair<Integer, IconicFontEngine> pair : positions) {
setSpan(pair.second.getTypeface(), spannableStringBuilder, pair.first);
}
return spannableStringBuilder;
}
public void doReplacement(SpannableStringBuilder text) {
if (key != null) {
String textAsString = text.toString();
int start = textAsString.indexOf(key);
text.replace(start, start + key.length(), replacement);
}
}
private static void recursivePrepareSpannableIndexes(
Context context,
String fullText,
SpannableStringBuilder text,
List<IconFontDescriptorWrapper> iconFontDescriptors,
int start) {
// Try to find a {...} in the string and extract expression from it
String stringText = text.toString();
int startIndex = stringText.indexOf("{", start);
if (startIndex == -1) return;
int endIndex = stringText.indexOf("}", startIndex) + 1;
if (endIndex == -1) return;
String expression = stringText.substring(startIndex + 1, endIndex - 1);
// Split the expression and retrieve the icon key
String[] strokes = expression.split(" ");
String key = strokes[0];
// Loop through the descriptors to find a key match
IconFontDescriptorWrapper iconFontDescriptor = null;
Icon icon = null;
for (int i = 0; i < iconFontDescriptors.size(); i++) {
iconFontDescriptor = iconFontDescriptors.get(i);
icon = iconFontDescriptor.getIcon(key);
if (icon != null) break;
}
// If no match, ignore and continue
if (icon == null) {
recursivePrepareSpannableIndexes(context, fullText, text, iconFontDescriptors, endIndex);
return;
}
// See if any more stroke within {} should be applied
float iconSizePx = -1;
int iconColor = Integer.MAX_VALUE;
float iconSizeRatio = -1;
boolean spin = false;
boolean baselineAligned = false;
for (int i = 1; i < strokes.length; i++) {
String stroke = strokes[i];
// Look for "spin"
if (stroke.equalsIgnoreCase("spin")) {
spin = true;
}
// Look for "baseline"
else if (stroke.equalsIgnoreCase("baseline")) {
baselineAligned = true;
}
// Look for an icon size
else if (stroke.matches("([0-9]*(\\.[0-9]*)?)dp")) {
iconSizePx = dpToPx(context, Float.valueOf(stroke.substring(0, stroke.length() - 2)));
} else if (stroke.matches("([0-9]*(\\.[0-9]*)?)sp")) {
iconSizePx = spToPx(context, Float.valueOf(stroke.substring(0, stroke.length() - 2)));
} else if (stroke.matches("([0-9]*)px")) {
iconSizePx = Integer.valueOf(stroke.substring(0, stroke.length() - 2));
} else if (stroke.matches("@dimen/(.*)")) {
iconSizePx = getPxFromDimen(context, context.getPackageName(), stroke.substring(7));
if (iconSizePx < 0)
throw new IllegalArgumentException("Unknown resource " + stroke + " in \"" + fullText + "\"");
} else if (stroke.matches("@android:dimen/(.*)")) {
iconSizePx = getPxFromDimen(context, ANDROID_PACKAGE_NAME, stroke.substring(15));
if (iconSizePx < 0)
throw new IllegalArgumentException("Unknown resource " + stroke + " in \"" + fullText + "\"");
} else if (stroke.matches("([0-9]*(\\.[0-9]*)?)%")) {
iconSizeRatio = Float.valueOf(stroke.substring(0, stroke.length() - 1)) / 100f;
}
// Look for an icon color
else if (stroke.matches("#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})")) {
iconColor = Color.parseColor(stroke);
} else if (stroke.matches("@color/(.*)")) {
iconColor = getColorFromResource(context, context.getPackageName(), stroke.substring(7));
if (iconColor == Integer.MAX_VALUE)
throw new IllegalArgumentException("Unknown resource " + stroke + " in \"" + fullText + "\"");
} else if (stroke.matches("@android:color/(.*)")) {
iconColor = getColorFromResource(context, ANDROID_PACKAGE_NAME, stroke.substring(15));
if (iconColor == Integer.MAX_VALUE)
throw new IllegalArgumentException("Unknown resource " + stroke + " in \"" + fullText + "\"");
} else {
throw new IllegalArgumentException("Unknown expression " + stroke + " in \"" + fullText + "\"");
}
}
// Replace the character and apply the typeface
text = text.replace(startIndex, endIndex, "" + icon.character());
text.setSpan(new CustomTypefaceSpan(icon,
iconFontDescriptor.getTypeface(context),
iconSizePx, iconSizeRatio, iconColor, spin, baselineAligned),
startIndex, startIndex + 1,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
recursivePrepareSpannableIndexes(context, fullText, text, iconFontDescriptors, startIndex);
}
private static SpannableStringBuilder analaysHash(SpannableStringBuilder builder, String messageID) {
if (builder == null) return builder;
String text = builder.toString();
if (text.length() < 1) return builder;
String s = "";
String tmp = "";
Boolean isHash = false;
int start = 0;
String enter = System.getProperty("line.separator");
for (int i = 0; i < text.length(); i++) {
s = text.substring(i, i + 1);
if (s.equals("#")) {
isHash = true;
tmp = "";
start = i;
continue;
}
if (isHash) {
if (!(s.matches("\\w") || s.equals("-"))) {
if (tmp.length() > 0) {
insertHashLink(tmp, builder, start, messageID);
}
tmp = "";
isHash = false;
} else {
tmp += s;
}
}
}
if (isHash) {
if (tmp.length() > 0) insertHashLink(tmp, builder, start, messageID);
}
return builder;
}
private static SpannableStringBuilder analaysAtSign(SpannableStringBuilder builder) {
if (builder == null) return builder;
String text = builder.toString();
if (text.length() < 1) return builder;
String s = "";
String tmp = "";
Boolean isAtSign = false;
int start = 0;
String enter = System.getProperty("line.separator");
for (int i = 0; i < text.length(); i++) {
s = text.substring(i, i + 1);
if (s.equals("@")) {
isAtSign = true;
tmp = "";
start = i;
continue;
}
if (isAtSign) {
if (!(s.matches("\\w") || s.equals("-"))) {
//if (s.equals("!") || s.equals("#") || s.equals("$") || s.equals("%") || s.equals("^") || s.equals("&") ||
// s.equals("(") || s.equals(")") || s.equals("-") || s.equals("+") || s.equals("=") || s.equals("!") ||
// s.equals("`") || s.equals("{") || s.equals("}") || s.equals("[") || s.equals("]") || s.equals(";") ||
// s.equals(":") || s.equals("'") || s.equals("?") || s.equals("<") || s.equals(">") || s.equals(",") || s.equals(" ") ||
// s.equals("\\") || s.equals("|") || s.equals("//") || s.codePointAt(0) == 8192 || s.equals(enter) || s.equals("")) {
if (tmp.length() > 0) {
insertAtSignLink(tmp, builder, start);
}
tmp = "";
isAtSign = false;
} else {
tmp += s;
}
}
}
if (isAtSign) {
if (tmp.length() > 0) insertAtSignLink(tmp, builder, start);
}
return builder;
}
/**
* 处理超链接
*
* @param context
* @param ssb
* @param urlColor
* @return
*/
public static SpannableStringBuilder getURLSSB(final Context context, final SpannableStringBuilder ssb, int urlColor) {
String[] urlTag = {"[url]", "[/url]"};
String regex = "\\[url\\](.*?)\\[/url\\]";
final String content = ssb.toString();
Matcher matcher = Pattern.compile(regex).matcher(content);
while (matcher.find()) {
final int textStart = matcher.start() + urlTag[0].length();
final int textEnd = matcher.end() - urlTag[1].length();
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View widget) {
String url = (content).subSequence(textStart, textEnd).toString();
JumpWebUtils.gotoWeb(context, "", url);
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.bgColor = Color.TRANSPARENT;
ds.setColor(ThemeUtils.getThemeColor(context));
}
};
ssb.setSpan(clickableSpan, textStart, textEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// ForegroundColorSpan contentColorSpan = new ForegroundColorSpan(
// urlColor);
// ssb.setSpan(contentColorSpan, textEnd,
// content.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
// ForegroundColorSpan typeColorSpan = new ForegroundColorSpan(context
// .getResources().getColor(
// R.color.text_azure));
// ssb.setSpan(typeColorSpan, textStart, textEnd,
// Spannable.SPAN_INCLUSIVE_INCLUSIVE);
// ssb.replace(matcher.start(), matcher.end(), ssb.subSequence(matcher.start() + urlTag[0].length(), matcher.end() - urlTag[1].length()));
// matcher = Pattern.compile(regex).matcher(ssb.toString());
}
//去除[url]和[/url]标签 start
String[] urlTagRegex = {"\\[url\\]", "\\[/url\\]"};
Matcher matcherUrlTag0 = Pattern.compile(urlTagRegex[0]).matcher(content);
while (matcherUrlTag0.find()) {
ssb.setSpan(
new ImageSpan(context, R.drawable.trans_1px), matcherUrlTag0.start(), matcherUrlTag0
.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
Matcher matcherUrlTag1 = Pattern.compile(urlTagRegex[1]).matcher(content);
while (matcherUrlTag1.find()) {
ssb.setSpan(
new ImageSpan(context, R.drawable.trans_1px), matcherUrlTag1.start(), matcherUrlTag1
.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
//去除[url]和[/url]标签 end
return ssb;
}
private void displayRichLinkMessage(final ViewHolder viewHolder, final Message message, boolean darkBackground) {
toggleWhisperInfo(viewHolder, message, true, darkBackground);
viewHolder.audioPlayer.setVisibility(View.GONE);
viewHolder.image.setVisibility(View.GONE);
viewHolder.gifImage.setVisibility(View.GONE);
viewHolder.download_button.setVisibility(View.GONE);
viewHolder.progressBar.setVisibility(View.GONE);
final SpannableStringBuilder body = new SpannableStringBuilder(replaceYoutube(activity.getApplicationContext(), message.getMergedBody().toString()));
final boolean dataSaverDisabled = activity.xmppConnectionService.isDataSaverDisabled();
viewHolder.richlinkview.setVisibility(View.VISIBLE);
if (mShowLinksInside) {
final double target = metrics.density * 200;
final int scaledH;
if (Math.max(100, 100) * metrics.density <= target) {
scaledH = (int) (100 * metrics.density);
} else if (Math.max(100, 100) <= target) {
scaledH = 100;
} else {
scaledH = (int) (100 / ((double) 100 / target));
}
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(WRAP_CONTENT, scaledH);
layoutParams.setMargins(0, (int) (metrics.density * 4), 0, (int) (metrics.density * 4));
viewHolder.richlinkview.setLayoutParams(layoutParams);
final String url = body.toString();
final String weburl;
final String lcUrl = url.toLowerCase(Locale.US).trim();
if (lcUrl.startsWith("http://") || lcUrl.startsWith("https://")) {
weburl = removeTrailingBracket(url);
} else {
weburl = "http://" + removeTrailingBracket(url);
}
viewHolder.richlinkview.setLink(weburl, message.getUuid(), dataSaverDisabled, activity.xmppConnectionService, new RichPreview.ViewListener() {
@Override
public void onSuccess(boolean status) {
}
@Override
public void onError(Exception e) {
e.printStackTrace();
viewHolder.richlinkview.setVisibility(View.GONE);
}
});
} else {
viewHolder.richlinkview.setVisibility(View.GONE);
}
}