Last active
May 18, 2018 14:21
-
-
Save li2/f962c1c6eb13b74796f2 to your computer and use it in GitHub Desktop.
SpannableString class to implement text with foreground color, background color, underline, strikethrough, bold & italic style, relative font size, superscript, subscript, URLs, clickable, text composed with image, and so on. #tags: android-view
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created by weiyi on 3/28/16. | |
* http://li2.me/2016/03/android-spannablestring-example.html | |
* https://github.com/li2/Learning_Android_Open_Source/tree/master/AndroidTextSample | |
*/ | |
public class SpannableStringApiActivity extends AppCompatActivity { | |
@Bind(R.id.textView) TextView mTextView; | |
@Bind(R.id.spannableForegroundColor) TextView mForegroundColorTextView; | |
@Bind(R.id.spannableBackgroundColor) TextView mBackgroundColorTextView; | |
@Bind(R.id.spannableUnderline) TextView mUnderlineTextView; | |
@Bind(R.id.spannableStrikethrough) TextView mStrikethroughTextView; | |
@Bind(R.id.spannableStyle) TextView mStyleTextView; | |
@Bind(R.id.spannableRelativeSize) TextView mRelativeSizeTextView; | |
@Bind(R.id.spannableSuperscript) TextView mSuperscriptTextview; | |
@Bind(R.id.spannableSubscript) TextView mSubscriptTextview; | |
@Bind(R.id.spannableUrl) TextView mUrlTextView; | |
@Bind(R.id.spannableImage) TextView mImageTextView; | |
private static final String CONTENT = "time is 52h 1314m . "; | |
private static final int START = 8; // the index of 5 | |
private static final int END = 17; // the index of m | |
private static final String URL = "http://li2.me"; | |
@Override | |
protected void onCreate(@Nullable Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_spannable_api); | |
ButterKnife.bind(this); | |
setTitle(R.string.action_title_spannable_string_api); | |
// plain text | |
mTextView.setText(CONTENT + "Plain"); | |
// foreground color text | |
ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.YELLOW); | |
setSpanText(CONTENT + "Colored", mForegroundColorTextView, foregroundColorSpan); | |
// background color text | |
BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.YELLOW); | |
setSpanText(CONTENT + "Highlighted", mBackgroundColorTextView, backgroundColorSpan); | |
// under line text | |
UnderlineSpan underlineSpan = new UnderlineSpan(); | |
setSpanText(CONTENT + "Underlined", mUnderlineTextView, underlineSpan); | |
// strikethrough text | |
StrikethroughSpan strikethroughSpan = new StrikethroughSpan(); | |
setSpanText(CONTENT + "Strikethrough", mStrikethroughTextView, strikethroughSpan); | |
// Style text | |
StyleSpan styleSpan = new StyleSpan(Typeface.BOLD_ITALIC); | |
setSpanText(CONTENT + "Bold & Italic", mStyleTextView, styleSpan); | |
// Relative size text | |
RelativeSizeSpan relativeLargerSizeSpan = new RelativeSizeSpan(1.5f); | |
RelativeSizeSpan relativeSmallerSizeSpan = new RelativeSizeSpan(0.5f); | |
setSpanText(CONTENT + "Large", mRelativeSizeTextView, relativeLargerSizeSpan); | |
// Superscript text | |
SuperscriptSpan superscriptSpan = new SuperscriptSpan(); | |
setSpanText(CONTENT + "Superscript & Small", mSuperscriptTextview, superscriptSpan, relativeSmallerSizeSpan); | |
// Subscript text | |
SubscriptSpan subscriptSpan = new SubscriptSpan(); | |
setSpanText(CONTENT + "Subscript & Small", mSubscriptTextview, subscriptSpan, relativeSmallerSizeSpan); | |
// Url text | |
setUrlSpanText(CONTENT + "URL&Clickable", mUrlTextView, URL); | |
// Image text | |
mImageTextView.getViewTreeObserver() | |
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { | |
@Deprecated | |
@Override | |
public void onGlobalLayout() { | |
int height = mImageTextView.getHeight(); | |
SpannableStringBuilder ssb = | |
addImageToText(SpannableStringApiActivity.this, R.drawable.ic_time, CONTENT + "Image", height); | |
mImageTextView.setText(ssb); | |
// must remove listener | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { | |
mImageTextView.getViewTreeObserver().removeOnGlobalLayoutListener(this); | |
} else { | |
mImageTextView.getViewTreeObserver().removeGlobalOnLayoutListener(this); | |
} | |
} | |
}); | |
} | |
private void setSpanText(String content, TextView textView, CharacterStyle span) { | |
SpannableStringBuilder ssb = new SpannableStringBuilder(content); | |
ssb.setSpan(span, START, END, 0); | |
textView.setText(ssb); | |
} | |
private void setSpanText(String content, TextView textView, CharacterStyle span1, CharacterStyle span2) { | |
SpannableStringBuilder ssb = new SpannableStringBuilder(content); | |
ssb.setSpan(span1, START, END, 0); | |
ssb.setSpan(span2, START, END, 0); | |
textView.setText(ssb); | |
} | |
private SpannableStringBuilder addImageToText(Context context, int drawableId, String text, int height) { | |
Drawable drawable = ContextCompat.getDrawable(context, drawableId); | |
int width = height * drawable.getIntrinsicWidth() / drawable.getIntrinsicHeight(); | |
drawable.setBounds(0, 0, width, height); | |
SpannableStringBuilder ssb = new SpannableStringBuilder(" " + text); | |
ssb.setSpan(new ImageSpan(drawable), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); | |
return ssb; | |
} | |
private void setUrlSpanText(String content, TextView textView, final String url) { | |
SpannableStringBuilder ssb = new SpannableStringBuilder(content); | |
ssb.setSpan(new ClickableSpan() { | |
@Override | |
public void onClick(View widget) { | |
Toast.makeText(SpannableStringApiActivity.this, url, Toast.LENGTH_LONG).show(); | |
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); | |
startActivity(i); | |
} | |
}, START, END, 0); | |
textView.setText(ssb); | |
// setting the MovementMethod on the TextView that contains the span, | |
// otherwise onClick will not be called. | |
textView.setMovementMethod(LinkMovementMethod.getInstance()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment