【工具类】使用Spannable设置TextView的各种样式

废话不说,直接上图

描述

上图包含以下各项操作:

  • textView内容中的关键字添加点击事件
  • textView内容添加下划线
  • textView内容添加删除线
  • textView内容中的关键字添加删除线
  • textView内容设置斜体
  • textView内容中的关键字设置颜色
  • textView内容中的关键字设置颜色+单位
  • textView内容中的关键字设置背景色
  • textView内容中的关键字添加超链接
  • textView内容中的关键字设置大小
  • textView内容中的关键字设置大小(关键字大小为默认字体大小的多少倍)

看代码

import android.graphics.Color;
import android.graphics.Paint;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.BackgroundColorSpan;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.RelativeSizeSpan;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.text.style.URLSpan;
import android.view.View;
import android.widget.TextView;

/**
 * # ******************************************************************
 * # ClassName:      TextSpannableUtils
 * # Description:    TextView设置Spannable风格的工具类
 * # Author:         atwang
 * # Version:        Ver 1.0
 * # Create Date     2021/10/12 14:28
 * # ******************************************************************
 * @author atwang
 */
public class TextSpannableUtils {

    private static ClickableSpanCallBack mClickableSpanCallBack;

    public TextSpannableUtils() {
    }

    /**
     * textView内容中的关键字设置颜色
     * @param content
     * @param keyWord
     * @param textView
     */
    public static void setPartColorSpan(String content, String keyWord, int resColorId, TextView textView) {
        int start = content.indexOf(keyWord);
        int end = start + keyWord.length();
        if (end!=0&&start!=-1){
            final SpannableStringBuilder builder = new SpannableStringBuilder();
            builder.append(content);
            ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(resColorId);
            builder.setSpan(foregroundColorSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            textView.setText(builder);
        }
    }

    /**
     * textView内容中的关键字设置颜色
     * @param keyWord   关键数据
     * @param unit         单位
     * @param textView   控件
     */
    public static void setPartTextColor(String keyWord, String unit, int resColorId, TextView textView) {
        int start = 0;
        int end = start + keyWord.length();
        String content = keyWord + unit;
        if (end != 0){
            final SpannableStringBuilder builder = new SpannableStringBuilder();
            builder.append(content);
            ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(resColorId);
            builder.setSpan(foregroundColorSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            textView.setText(builder);
        }
    }

    /**
     * textView内容中的关键字设置背景色
     * @param content
     * @param keyWord
     * @param textView
     */
    public static void setPartBackgroundColor(String content, String keyWord, int resColorId, TextView textView) {
        int start = content.indexOf(keyWord);
        int end = start + keyWord.length();
        if (end!=0&&start!=-1){
            final SpannableStringBuilder builder = new SpannableStringBuilder();
            builder.append(content);
            BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(resColorId);
            builder.setSpan(backgroundColorSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            textView.setText(builder);
        }
    }

    /**
     * textView内容中的关键字设置大小
     * @param content   关键数据
     * @param keyWord    单位
     * @param textView   控件
     */
    public static void setPartTextSize( String content, String keyWord, int size, TextView textView) {
        int start = content.indexOf(keyWord);
        int end = start + keyWord.length();
        if (end!=0&&start!=-1){
            final SpannableStringBuilder builder = new SpannableStringBuilder();
            builder.append(content);
            //第二个参数boolean dip,如果为true,表示前面的字体大小单位为dip,否则为像素
            AbsoluteSizeSpan absoluteSizeSpan = new AbsoluteSizeSpan(size,true);
            builder.setSpan(absoluteSizeSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            textView.setText(builder);
        }
    }

    /**
     * textView内容中的关键字设置大小
     * @param content   关键数据
     * @param keyWord    单位
     * @param textView   控件
     */
    public static void setPartRelativeSize( String content, String keyWord, float multiple, TextView textView) {
        int start = content.indexOf(keyWord);
        int end = start + keyWord.length();
        if (end!=0&&start!=-1){
            final SpannableStringBuilder builder = new SpannableStringBuilder();
            builder.append(content);
            //参数表示设置关键字大小为默认字体大小的多少倍
            RelativeSizeSpan relativeSizeSpan = new RelativeSizeSpan(multiple);
            builder.setSpan(relativeSizeSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            textView.setText(builder);
        }
    }

    /**
     * textView内容设置斜体
     * @param content
     * @param textView
     */
    public static void setPartItalic(String content, TextView textView){
        SpannableString sp = new SpannableString(content);
        sp.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, content.length(), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
        textView.setText(sp);
    }

    /**
     * textView内容中的关键字设置斜体
     * @param content
     * @param keyWord
     * @param textView
     */
    public static void setPartItalic(String content, String keyWord, TextView textView){
        SpannableStringBuilder builder = new SpannableStringBuilder(content);
        int start = content.indexOf(keyWord);
        if (start < 0) {
            if (content.length() > 0) {
                textView.setText(content);
            } else {
                textView.setText("");
            }
            return;
        }
        int end = start + keyWord.length();
        builder.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        if (textView != null) {
            textView.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG);
            textView.setText(builder);
        }
    }

    /**
     * textView内容添加下划线
     * @param textView
     */
    public static void setPartUnderline(TextView textView){
        //下划线/抗锯齿
        textView.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG|Paint.ANTI_ALIAS_FLAG);
    }

    /**
     * textView内容中的关键字添加下划线
     * @param content
     * @param keyWord
     * @param textView
     */
    public static void setPartUnderline(String content, String keyWord, TextView textView){
        SpannableStringBuilder builder = new SpannableStringBuilder(content);
        int start = content.indexOf(keyWord);
        if (start < 0) {
            if (content.length() > 0) {
                textView.setText(content);
            } else {
                textView.setText("");
            }
            return;
        }
        int end = start + keyWord.length();
        builder.setSpan(new StyleSpan( Paint.UNDERLINE_TEXT_FLAG),start ,end, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
        if (textView != null) {
            textView.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG);
            textView.setText(builder);
            textView.setMovementMethod(LinkMovementMethod.getInstance());
        }
    }

    /**
     * textView内容添加删除线
     * @param textView
     */
    public static void setPartDeleteLine(TextView textView){
        //删除线/抗锯齿
        textView.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG|Paint.ANTI_ALIAS_FLAG);
    }

    /**
     * textView内容添加删除线
     * @param content
     * @param textView
     */
    public static void setPartDeleteLine(String content, TextView textView){
        SpannableString sp = new SpannableString(content);
        sp.setSpan(new StrikethroughSpan(), 0, content.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        textView.setText(sp);
    }

    /**
     * textView内容中的关键字添加删除线
     * @param content
     * @param keyWord
     * @param textView
     */
    public static void setPartDeleteLine(String content, String keyWord, TextView textView){
        SpannableStringBuilder builder = new SpannableStringBuilder(content);
        int start = content.indexOf(keyWord);
        if (start < 0) {
            if (content.length() > 0) {
                textView.setText(content);
            } else {
                textView.setText("");
            }
            return;
        }
        int end = start + keyWord.length();
        builder.setSpan(new StrikethroughSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        if (textView != null) {
            textView.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG);
            textView.setText(builder);
        }
    }

    /**
     *  textView内容中的关键字添加超链接
     * @param content
     * @param keyWord
     * @param url
     * @param textView
     */
    public static void setPartUrlClick(String content, String keyWord, String url, TextView textView) {
        SpannableStringBuilder builder = new SpannableStringBuilder(content);
        int start = content.indexOf(keyWord);
        if (start < 0) {
            if (content.length() > 0) {
                textView.setText(content);
            } else {
                textView.setText("");
            }
            return;
        }
        int end = start + keyWord.length();
        builder.setSpan(new URLSpan(url), start, end,  Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        builder.setSpan(new ForegroundColorSpan(Color.BLUE), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        builder.setSpan(new StyleSpan(Paint.UNDERLINE_TEXT_FLAG), start, end, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
        if (textView != null) {
            textView.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG);
            textView.setText(builder);
            textView.setMovementMethod(LinkMovementMethod.getInstance());
        }
    }

    /**
     *  textView内容中的关键字添加点击事件
     * @param content
     * @param keyWord
     * @param resColorId
     * @param textView
     */
    public static void setPartClick(String content, String keyWord, int resColorId, TextView textView) {
        SpannableStringBuilder builder = new SpannableStringBuilder(content);
        int start = content.indexOf(keyWord);
        if (start < 0) {
            if (content.length() > 0) {
                textView.setText(content);
            } else {
                textView.setText("");
            }
            return;
        }
        int end = start + keyWord.length();
        builder.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                if (mClickableSpanCallBack != null) {
                    mClickableSpanCallBack.onClick();
                    avoidHintColor(widget);
                }
            }

            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
            }
        }, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        builder.setSpan(new ForegroundColorSpan(resColorId), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        builder.setSpan(new StyleSpan(Paint.UNDERLINE_TEXT_FLAG), start, end, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
        if (textView != null) {
            textView.getPaint().setFlags(Paint.ANTI_ALIAS_FLAG);
            textView.setText(builder);
            textView.setMovementMethod(LinkMovementMethod.getInstance());
        }
    }

    /**
     * 设置选中文字背景色
     * @param view
     */
    private static void avoidHintColor(View view){
        if(view instanceof TextView) {
            ((TextView)view).setHighlightColor(Color.TRANSPARENT);
        }
    }

    public void setClickableSpanCallBack(ClickableSpanCallBack clickableSpanCallBack) {
        mClickableSpanCallBack = clickableSpanCallBack;
    }

    public interface ClickableSpanCallBack{
        void onClick();
    }
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值