SpannableString花式文本混排

情景

使用一个TextView混排多种不同颜色、大小等风格。

效果

SpannableString

这是文本的类,其内容是不可变的,但标记对象可以附加和分离。
This is the class for text whose content is immutable but to which markup objects can be attached and detached.

可以理解为一个可以设置每个字符风格的String,主要的方法在于setSpan()。

setSpan

/**
 * 设置指定区域的风格
 *
 * @param what  风格类型
 * @param start 开始的位置。从0开始,不包含此位置
 * @param end   结束位置。包含此位置
 * @param flags 可以编辑时风格是否延续
 */
public void setSpan(Object what, int start, int end, int flags)

what 风格

参照: Android中强大的SpannableStringBuilder

  • BackgroundColorSpan : 文本背景色
  • ForegroundColorSpan : 文本颜色
  • MaskFilterSpan : 修饰效果
  • RasterizerSpan : 光栅效果
  • StrikethroughSpan : 删除线
  • SuggestionSpan : 相当于占位符
  • UnderlineSpan : 下划线
  • AbsoluteSizeSpan : 文本字体(绝对大小)
  • DynamicDrawableSpan : 设置图片,基于文本基线或底部对齐。
  • ImageSpan : 图片
  • RelativeSizeSpan : 相对大小(文本字体)
  • ScaleXSpan : 基于x轴缩放
  • StyleSpan : 字体样式:粗体、斜体等
  • SubscriptSpan : 下标
  • SuperscriptSpan : 上标
  • TextAppearanceSpan : 文本外貌(包括字体、大小、样式和颜色)
  • TypefaceSpan : 文本字体
  • URLSpan : 文本超链接
  • ClickableSpan : 点击事件

flags 延续范围

  • SPAN_INCLUSIVE_EXCLUSIVE : 包括前面,不包括后面
  • SPAN_INCLUSIVE_INCLUSIVE : 包括前面,包括后面
  • SPAN_EXCLUSIVE_EXCLUSIVE
  • SPAN_EXCLUSIVE_INCLUSIVE

举个栗子:

“字”后面,“颜”前面,输入内容会和“颜色”效果一直,而“色”后面的内容不会改变风格。(脑补画面…)

SpannableString text = new SpannableString("文字颜色改变");
text.setSpan(new ForegroundColorSpan(ContextCompat.getColor(this, R.color.colorAccent)), 2, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mEditTextColor.setText(text);

效果所有代码

/**
 * SpanableString 类使用
 * 实现花式文本的混排
 *
 * @author fengzhen
 * @version v1.0, 2017/10/12 15:41
 */
public class MainActivity extends AppCompatActivity {

    @BindView(R.id.edit_text_color)
    EditText mEditTextColor;
    @BindView(R.id.tv_test_background)
    TextView mTvTestBackground;
    @BindView(R.id.tv_under_line)
    TextView mTvUnderLine;
    @BindView(R.id.tv_text_size)
    TextView mTvTextSize;
    @BindView(R.id.tv_image)
    TextView mTvImage;
    @BindView(R.id.tv_superscript)
    TextView mTvSuperscript;
    @BindView(R.id.tv_hyperlink)
    TextView mTvHyperlink;
    @BindView(R.id.tv_click)
    TextView mTvClick;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        setTextColor();
        setTextBackground();
        setTextUnderline();
        setTextSize();
        setTextImage();
        setTextSuperscript();
        setTextHyperlink();
        setTextClick();
    }

    private void setTextClick() {
        SpannableString text = new SpannableString("文字点击效果");
        text.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                Toast.makeText(MainActivity.this, "点击了!", Toast.LENGTH_SHORT).show();
                mTvClick.setFocusable(false);
            }

            @Override
            public void updateDrawState(TextPaint ds) {
                // 文字颜色
                ds.setColor(Color.RED);
                // 取消下划线
                ds.setUnderlineText(false);
            }
        }, 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        mTvClick.setText(text);
        mTvClick.setMovementMethod(LinkMovementMethod.getInstance());
    }

    private void setTextHyperlink() {
        SpannableString text = new SpannableString("文字超链接效果");
        text.setSpan(new URLSpan("https://www.baidu.com/?tn=57095150_2_oem_dg"), 2, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        mTvHyperlink.setText(text);
        mTvHyperlink.setMovementMethod(LinkMovementMethod.getInstance());
    }

    private void setTextSuperscript() {
        SpannableString text = new SpannableString("文字上标效果");
        text.setSpan(new SuperscriptSpan(), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        mTvSuperscript.setText(text);
    }

    private void setTextImage() {
        SpannableString text = new SpannableString("文字变成图片效果");
        text.setSpan(new ImageSpan(this, R.mipmap.ic_launcher), 4, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        mTvImage.setText(text);
    }

    private void setTextSize() {
        SpannableString text = new SpannableString("文字大小改变");
        text.setSpan(new AbsoluteSizeSpan(44), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        mTvTextSize.setText(text);
    }

    private void setTextUnderline() {
        SpannableString text = new SpannableString("文字下划线效果");
        text.setSpan(new UnderlineSpan(), 2, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        mTvUnderLine.setText(text);
    }

    private void setTextBackground() {
        SpannableString text = new SpannableString("文字背景变色");
        text.setSpan(new BackgroundColorSpan(ContextCompat.getColor(this, R.color.colorAccent)), 2, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        mTvTestBackground.setText(text);
    }

    private void setTextColor() {
        SpannableString text = new SpannableString("文字颜色改变");
        text.setSpan(new ForegroundColorSpan(ContextCompat.getColor(this, R.color.colorAccent)), 2, 4, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        mEditTextColor.setText(text);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章