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);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章