下面列出了android.text.SpannableString#valueOf ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Scans the text of the provided TextView and turns all occurrences of the entity types
* specified by {@code options} into clickable links. If links are found, this method
* removes any pre-existing {@link TextLinkSpan} attached to the text (to avoid
* problems if you call it repeatedly on the same text) and sets the movement method for the
* TextView to LinkMovementMethod.
*
* <p><strong>Note:</strong> This method returns immediately but generates the links with
* the specified classifier on a background thread. The generated links are applied on the
* calling thread.
*
* @param textView TextView whose text is to be marked-up with links
* @param params optional parameters to specify how to generate the links
* @param executor Executor that runs the background task
* @param callback Callback that receives the final status of the background task execution
*
* @return a future that may be used to interrupt or query the background task
* @hide
*/
@UiThread
public static Future<Void> addLinksAsync(
@NonNull TextView textView,
@Nullable TextLinksParams params,
@Nullable Executor executor,
@Nullable Consumer<Integer> callback) {
Preconditions.checkNotNull(textView);
final CharSequence text = textView.getText();
final Spannable spannable = (text instanceof Spannable)
? (Spannable) text : SpannableString.valueOf(text);
final Runnable modifyTextView = () -> {
addLinkMovementMethod(textView);
if (spannable != text) {
textView.setText(spannable);
}
};
return addLinksAsync(spannable, textView.getTextClassifier(),
params, executor, callback, modifyTextView);
}
/**
* Retrieves SpannableString containing the target span in the accessibility node. The content
* description and text of the node is checked in order.
*
* @param node The AccessibilityNodeInfoCompat where the text comes from.
* @param spanClass Class of target span.
* @return SpannableString with at least 1 target span. null if no target span found in the node.
*/
public static <T> @Nullable SpannableString getStringWithTargetSpan(
AccessibilityNodeInfoCompat node, Class<T> spanClass) {
CharSequence text = node.getContentDescription();
if (isEmptyOrNotSpannableStringType(text)) {
text = AccessibilityNodeInfoUtils.getText(node);
if (isEmptyOrNotSpannableStringType(text)) {
return null;
}
}
SpannableString spannable = SpannableString.valueOf(text);
T[] spans = spannable.getSpans(0, spannable.length(), spanClass);
if (spans == null || spans.length == 0) {
return null;
}
return spannable;
}
@Override
public void bindData(RelevantTopicBean relevantTopicBean, int position) {
mRelevantTopicBean = relevantTopicBean;
LocalDate date = relevantTopicBean.getCreatedAt().toLocalDate();
int year = date.getYear();
int month = date.getMonthValue();
int day = date.getDayOfMonth();
if (year == OffsetDateTime.now().getYear()) {
mTxtDate.setText(mContext.getString(R.string.month__day, month, day));
} else {
SpannableString spannableTitle = SpannableString.valueOf(mContext.getString(R.string.month__day__year, month, day, year));
spannableTitle.setSpan(new ForegroundColorSpan(ContextCompat.getColor(mContext, R.color.text_topic_detail_news_author)),
spannableTitle.toString().indexOf("\n") + 1,
spannableTitle.toString().indexOf("\n") + 5,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
mTxtDate.setText(spannableTitle);
}
mTxtContent.setText(relevantTopicBean.getTitle());
mDividerTop.setVisibility(getItemViewType() == VIEW_TYPE_TOP || getItemViewType() == VIEW_TYPE_ONLY_ONE ? View.INVISIBLE : View.VISIBLE);
mDividerBottom.setVisibility(getItemViewType() == VIEW_TYPE_BOTTOM || getItemViewType() == VIEW_TYPE_ONLY_ONE ? View.INVISIBLE : View.VISIBLE);
}
public CharSequence getformatedSearchSnippet() {
//TODO implement improved snippet function
String CleanedSearchString = " " + ArabicUtilities.cleanTextForSearchingWthStingBuilder(searchString) + " ";
StringBuilder cleanedUnformattedPage = new StringBuilder(ArabicUtilities.cleanTextForSearchingWthStingBuilder(unformatedPage));
int firstMatchStart = cleanedUnformattedPage.indexOf(CleanedSearchString);
cleanedUnformattedPage.delete(0, Math.max(firstMatchStart - 100, 0));
cleanedUnformattedPage.delete(
Math.min(firstMatchStart + CleanedSearchString.length() + 100, cleanedUnformattedPage.length())
, cleanedUnformattedPage.length());
cleanedUnformattedPage.insert(0, "...");
cleanedUnformattedPage.append("...");
Spannable snippet = SpannableString.
valueOf(cleanedUnformattedPage.toString());
int index = TextUtils.indexOf(snippet, CleanedSearchString);
while (index >= 0) {
snippet.setSpan(new BackgroundColorSpan(0xFF8B008B), index, index
+ CleanedSearchString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
index = TextUtils.indexOf(snippet, CleanedSearchString, index + CleanedSearchString.length());
}
return snippet;
}
private void clickify(int start, int end, ClickSpan.OnClickListener listener) {
CharSequence text = messageTextView.getText();
ClickSpan span = new ClickSpan(listener);
if (start == -1) {
return;
}
if (text instanceof Spannable) {
((Spannable) text).setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
SpannableString s = SpannableString.valueOf(text);
s.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
messageTextView.setText(s);
}
}
/**
* Sets (and highlights) the URL text of the second line of the omnibox suggestion.
*
* @param result The suggestion containing the URL.
* @return Whether the URL was highlighted based on the user query.
*/
private boolean setUrlText(OmniboxResultItem result) {
OmniboxSuggestion suggestion = result.getSuggestion();
Spannable str = SpannableString.valueOf(suggestion.getDisplayText());
boolean hasMatch = applyHighlightToMatchRegions(
str, suggestion.getDisplayTextClassifications());
showDescriptionLine(str, true);
return hasMatch;
}
@Test
public void givenSpan_whenMessage_thenMessageSet() {
SnackbarBuilder builder = createBuilder();
Spannable spannable = new SpannableString("testMessage");
spannable.setSpan(new ForegroundColorSpan(Color.CYAN), 0, spannable.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.message(spannable);
assertThat(builder.message.toString()).isEqualTo("testMessage");
SpannableString actual = SpannableString.valueOf(builder.message);
ForegroundColorSpan[] spans = actual.getSpans(0, spannable.length(), ForegroundColorSpan.class);
assertThat(spans).hasSize(1);
assertThat(spans[0].getForegroundColor()).isEqualTo(Color.CYAN);
}
@Override
protected void onPause() {
if (D) Log.d(TAG, "onPause()");
super.onPause();
//alert users that terminal was not logging while out of focus
BusData data = new BusData(getString(R.string.msg_error_terminal_focus_lost), BusDataType.ERROR, false);
terminalAppend(data);
//persist terminal contents
SpannableString span = SpannableString.valueOf(mTxtTerminal.getText());
AppState.setString(getApplicationContext(), R.string.app_state_s_termninal_contents, Html.toHtml(span));
}
/**
* Scans the text of the provided TextView and turns all occurrences of the
* link types indicated in the mask into clickable links. If matches are
* found the movement method for the TextView is set to LinkMovementMethod.
*/
public static final boolean addLinks(final TextView text, final int mask) {
if (mask == 0) {
return false;
}
final CharSequence t = text.getText();
if (t instanceof Spannable) {
if (LinkifyCompat.addLinks((Spannable) t, mask)) {
LinkifyCompat.addLinkMovementMethod(text);
return true;
}
return false;
} else {
final SpannableString s = SpannableString.valueOf(t);
if (LinkifyCompat.addLinks(s, mask)) {
LinkifyCompat.addLinkMovementMethod(text);
text.setText(s);
return true;
}
return false;
}
}
private void addReadLess(final TextView textView, final CharSequence text) {
textView.setMaxLines(Integer.MAX_VALUE);
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text)
.append(lessLabel);
SpannableString ss = SpannableString.valueOf(spannableStringBuilder);
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View view) {
new Handler().post(new Runnable() {
@Override
public void run() {
addReadMoreTo(textView, text);
}
});
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(labelUnderLine);
ds.setColor(lessLabelColor);
}
};
ss.setSpan(clickableSpan, ss.length() - lessLabel.length(), ss.length() , Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(ss);
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
public void addEmotions(EditText et, String txt, Map<String, Integer> smiles) {
String hackTxt;
if (txt.startsWith("[") && txt.endsWith("]")) {
hackTxt = txt + " ";
} else {
hackTxt = txt;
}
SpannableString value = SpannableString.valueOf(hackTxt);
addEmotions(value, smiles);
et.setText(value);
}
/**
* 解析表情
* @param message
* @return
*/
private CharSequence convertNormalStringToSpannableString(String message) {
/* // Direct use of Pattern:
Pattern p = Pattern.compile("Hello, (\\S+)");
Matcher m = p.matcher(inputString);
while (m.find()) { // Find each match in turn; String can't do this.
String name = m.group(1); // Access a submatch group; String can't do this.
}*/
/*//不知道是干嘛的。。
SpannableString spannableString ;
if(message.startsWith("[") && message.endsWith("]")){
spannableString = SpannableString.valueOf(message +" ");
}else{
spannableString = SpannableString.valueOf(message);
}*/
SpannableString spannableString = SpannableString.valueOf(message);
//匹配 表情 字符串
Matcher matcher = patter.matcher(spannableString);
while(matcher.find()){
String keyStr = matcher.group(0);
int start = matcher.start();
int end = matcher.end();
//过长就不是表情了 所以只检测长度小于8的字符串
if(end - start <8){
//判断是否有此表情
if(mFaceMap.containsKey(keyStr)){
int faceId = mFaceMap.get(keyStr);
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),faceId);
if(bitmap != null){
ImageSpan imageSpan = new ImageSpan(context, bitmap);
spannableString.setSpan(imageSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
}
return spannableString;
}
/**
* Sets (and highlights) the URL text of the second line of the omnibox suggestion.
*
* @param result The suggestion containing the URL.
* @return Whether the URL was highlighted based on the user query.
*/
private boolean setUrlText(OmniboxResultItem result) {
OmniboxSuggestion suggestion = result.getSuggestion();
Spannable str = SpannableString.valueOf(suggestion.getDisplayText());
boolean hasMatch = applyHighlightToMatchRegions(
str, suggestion.getDisplayTextClassifications());
showDescriptionLine(str, true);
return hasMatch;
}
public static SpannableString applyColorSpan(@NonNull String normal, @NonNull String applyTo, @ColorInt final int color) {
SpannableStringBuilder s = new SpannableStringBuilder(normal + applyTo);
s.setSpan(new ForegroundColorSpan(color), normal.length(), normal.length() + applyTo.length(), 0);
return SpannableString.valueOf(s);
}
/**
* Generates a Spannable with text formatted at the word level.
*
* @param wholeStringTranscript the whole transcript, formatted to have no leading spaces and a
* single trailing space
* @param languageCode string language code, for example "en-us" or "ja"
* @param words the list of words contained in wholeStringTranscript
* @param colorFunction maps a word to a hex color
*/
private Spannable addPerWordColoredStringToResult(
String wholeStringTranscript,
String languageCode,
List<TranscriptionResult.Word> words,
boolean precededByLineBreak,
ColorByWordFunction colorFunction) {
StringBuilder rawTranscript = new StringBuilder(wholeStringTranscript);
boolean wordFound = false;
String color = "";
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
StringBuilder intermediateBuilder = new StringBuilder();
// Group adjacent words of the same color within the same span tag.
// Traverse in reverse then a space divider will be at the end of word.
List<TranscriptionResult.Word> reverseWords = Lists.reverse(words);
for (int wordIndex = 0; wordIndex < reverseWords.size(); ++wordIndex) {
TranscriptionResult.Word word = reverseWords.get(wordIndex);
String nextColor = colorFunction.getColor(word);
if (wordFound) {
if (!color.equals(nextColor)) {
spannableStringBuilder.insert(
0, makeColoredString(intermediateBuilder.toString(), color));
intermediateBuilder = new StringBuilder();
wordFound = false;
}
if (options.getSpeakerIndicationStyle() == SpeakerIndicationStyle.SHOW_SPEAKER_NUMBER) {
// If the speaker has changed or if the text was preceded by a space, add a chevron.
int previousSpeaker = reverseWords.get(wordIndex - 1).getSpeakerInfo().getSpeakerId();
if (word.getSpeakerInfo().getSpeakerId() != previousSpeaker) {
boolean needsAdditionalNewline = previousSpeaker != -1 && !precededByLineBreak;
intermediateBuilder.insert(
0,
newSpeakerChevron(
reverseWords.get(wordIndex - 1).getSpeakerInfo().getSpeakerId(),
needsAdditionalNewline));
spannableStringBuilder.insert(
0, makeColoredString(intermediateBuilder.toString(), color));
intermediateBuilder = new StringBuilder();
wordFound = false;
}
}
}
// We'll try to find previous word if we can't find current word in the rawTranscript.
// Append the string started from the word to the end if found.
wordFound |=
checkWordExistedThenAdd(
rawTranscript, intermediateBuilder, formatWord(languageCode, word.getText()));
color = nextColor;
}
boolean forceChevron =
precededByLineBreak || words.get(0).getSpeakerInfo().getSpeakerId() != lastSpeakerId;
intermediateBuilder.insert(0, rawTranscript.toString());
if (options.getSpeakerIndicationStyle() == SpeakerIndicationStyle.SHOW_SPEAKER_NUMBER
&& intermediateBuilder.length() != 0
&& forceChevron) {
intermediateBuilder.insert(
0,
newSpeakerChevron(
words.get(0).getSpeakerInfo().getSpeakerId(),
lastSpeakerId != -1 && !precededByLineBreak));
}
spannableStringBuilder.insert(0, makeColoredString(intermediateBuilder.toString(), color));
return SpannableString.valueOf(spannableStringBuilder);
}
private void setTextViewDeleted(TextView tv) {
SpannableString ss = SpannableString.valueOf(tv.getText());
ss.setSpan(new StrikethroughSpan(), 0, ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(ss);
}
@Override
public void bindData(TopicDetailBean topicBean, boolean isPullToRefresh) {
this.mTopicBean = topicBean;
mTxtTopicTitle.setText(mTopicBean.getTitle().trim());
if (null != mTopicBean.getFormattedPublishDate()) {
mTxtTopicTime.setText(mTopicBean.getFormattedPublishDate().toLocalDate().toString() + " " +
mTopicBean.getFormattedPublishDate().toLocalTime().toString().substring(0, 8));
} else {
mTxtTopicTime.setVisibility(View.GONE);
}
if (TextUtils.isEmpty(mTopicBean.getSummary().trim())) {
mTxtTopicDescription.setVisibility(View.GONE);
} else {
mTxtTopicDescription.setText(mTopicBean.getSummary().trim());
mTxtTopicDescription.setVisibility(View.VISIBLE);
}
mTitleContainer.removeAllViews();
if (mTopicBean.getNewsArray() == null || mTopicBean.getNewsArray().isEmpty()) {
mTitleContainer.setVisibility(View.GONE);
} else {
mTitleContainer.setVisibility(View.VISIBLE);
for (final TopicNewsBean topic : mTopicBean.getNewsArray()) {
TextView textView = new TextView(getContext());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
textView.setLayoutParams(params);
textView.setPadding(10, 16, 10, 16);
textView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_topic_detail_ring, 0, 0, 0);
textView.setCompoundDrawablePadding(15);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
/*textView.setTextColor(ContextCompat.getColor(getContext(),
ResourceUtil.getResource(getActivity(), R.attr.readhubTextColorPrimary)));*/
textView.setTextColor(ContextCompat.getColor(getContext(), R.color.text_topic_detail_news_title));
//textView.setBackgroundResource(R.drawable.selector_btn_background);
if (TextUtils.isEmpty(topic.getSiteName())) {
textView.setText(topic.getTitle());
} else {
SpannableString spannableTitle = SpannableString.valueOf(getContext().getString(R.string.title___site_name, topic.getTitle(), topic.getSiteName()));
spannableTitle.setSpan(new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.text_topic_detail_news_author)),
topic.getTitle().length(),
topic.getTitle().length() + topic.getSiteName().length() + 2,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableTitle);
}
textView.setOnClickListener(v -> {
String url = null;
if (!TextUtils.isEmpty(topic.getMobileUrl())) {
url = topic.getMobileUrl();
} else {
url = topic.getUrl();
}
if (!TextUtils.isEmpty(url)) {
RxBus.getInstance().post(new OpenWebSiteEvent(url, topic.getTitle()));
}
});
mTitleContainer.addView(textView);
}
}
if (null != mTopicBean.getTimeline() && null != mTopicBean.getTimeline().getTopics() && 0 < mTopicBean.getTimeline().getTopics().size()) {
mTimelineAdapter.addItems(mTopicBean.getTimeline().getTopics());
mTimelineContainer.setVisibility(View.VISIBLE);
} else {
mTimelineContainer.setVisibility(View.GONE);
}
if (!mTopicBean.getEntityEventTopics().isEmpty()) {
mRelativeTopicContainer.setVisibility(View.VISIBLE);
ArrayList<EntityEventTopicBean> entityEventTopics = mTopicBean.getEntityEventTopics();
mRelativeTopic.setAdapter(new TagAdapter<EntityEventTopicBean>(entityEventTopics) {
@Override
public View getView(FlowLayout parent, int position, EntityEventTopicBean entityEventTopicBean) {
TextView item = (TextView) getLayoutInflater().inflate(R.layout.item_relevant_topic, mRelativeTopic, false);
item.setText(entityEventTopicBean.getEntityName() + entityEventTopicBean.getEventTypeLabel());
return item;
}
});
mRelativeTopic.setOnTagClickListener((view, position, parent) -> {
String topicId = String.valueOf(entityEventTopics.get(position).getEntityId());
long order = mTopicBean.getOrder();
RelevantTopicWindow window = new RelevantTopicWindow(getActivity(), topicId, order);
window.showOnAnchor(view, RelativePopupWindow.VerticalPosition.ABOVE, RelativePopupWindow.HorizontalPosition.CENTER, true);
setBackgroundAlpha(0.7f);
window.setOnDismissListener(() -> {
setBackgroundAlpha(1f);
if (((TagView) view).isChecked()) {
((TagView) view).setChecked(false);
}
});
return true;
});
} else {
mRelativeTopicContainer.setVisibility(View.GONE);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setButtonBackVisible(false);
setButtonNextVisible(false);
setButtonCtaVisible(true);
setButtonCtaTintMode(BUTTON_CTA_TINT_MODE_BACKGROUND);
TypefaceSpan labelSpan = new TypefaceSpan(
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? "sans-serif-medium" : "sans serif");
SpannableString label = SpannableString
.valueOf(getString(R.string.label_button_cta_canteen_intro));
label.setSpan(labelSpan, 0, label.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
setButtonCtaLabel(label);
setPageScrollDuration(500);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setPageScrollInterpolator(android.R.interpolator.fast_out_slow_in);
}
addSlide(new SimpleSlide.Builder()
.title(R.string.title_canteen_intro1)
.description(R.string.description_canteen_intro1)
.image(R.drawable.art_canteen_intro1)
.background(R.color.color_canteen)
.backgroundDark(R.color.color_dark_canteen)
.layout(R.layout.slide_canteen)
.build());
addSlide(new SimpleSlide.Builder()
.title(R.string.title_canteen_intro2)
.description(R.string.description_canteen_intro2)
.image(R.drawable.art_canteen_intro2)
.background(R.color.color_canteen)
.backgroundDark(R.color.color_dark_canteen)
.layout(R.layout.slide_canteen)
.build());
addSlide(new SimpleSlide.Builder()
.title(R.string.title_canteen_intro3)
.description(R.string.description_canteen_intro3)
.image(R.drawable.art_canteen_intro3)
.background(R.color.color_canteen)
.backgroundDark(R.color.color_dark_canteen)
.layout(R.layout.slide_canteen)
.build());
autoplay(2500, INFINITE);
}
/**
* Applies a regex to the text of a TextView turning the matches into links.
* If links are found then UrlSpans are applied to the link text match
* areas, and the movement method for the text is changed to
* LinkMovementMethod.
*
* @param text
* TextView whose text is to be marked-up with links
* @param p
* Regex pattern to be used for finding links
* @param scheme
* Url scheme string (eg <code>http://</code> to be prepended to
* the url of links that do not have a scheme specified in the
* link text
* @param matchFilter
* The filter that is used to allow the client code additional
* control over which pattern matches are to be converted into
* links.
*/
public static final void addLinks(final TextView text, final Pattern p,
final String scheme, final MatchFilter matchFilter,
final TransformFilter transformFilter) {
final SpannableString s = SpannableString.valueOf(text.getText());
if (LinkifyCompat.addLinks(s, p, scheme, matchFilter, transformFilter)) {
text.setText(s);
LinkifyCompat.addLinkMovementMethod(text);
}
}
/**
* Applies a regex to the text of a TextView turning the matches into
* links. If links are found then UrlSpans are applied to the link
* text match areas, and the movement method for the text is changed
* to LinkMovementMethod.
*
* @param text TextView whose text is to be marked-up with links.
* @param pattern Regex pattern to be used for finding links.
* @param defaultScheme The default scheme to be prepended to links if the link does not
* start with one of the <code>schemes</code> given.
* @param schemes Array of schemes (eg <code>http://</code>) to check if the link found
* contains a scheme. Passing a null or empty value means prepend defaultScheme
* to all links.
* @param matchFilter The filter that is used to allow the client code additional control
* over which pattern matches are to be converted into links.
* @param transformFilter Filter to allow the client code to update the link found.
*/
public static final void addLinks(@NonNull TextView text, @NonNull Pattern pattern,
@Nullable String defaultScheme, @Nullable String[] schemes,
@Nullable MatchFilter matchFilter, @Nullable TransformFilter transformFilter) {
SpannableString spannable = SpannableString.valueOf(text.getText());
boolean linksAdded = addLinks(spannable, pattern, defaultScheme, schemes, matchFilter,
transformFilter);
if (linksAdded) {
text.setText(spannable);
addLinkMovementMethod(text);
}
}