android TextView部分文字可点击 不同大小文字添加背景且居中显示

关于SpannableString与SpannableStringBuilder更多可点击:
https://www.jianshu.com/p/84067ad289d2
http://blog.csdn.net/harvic880925/article/details/38984705
修改默认点击事件:http://dingbuoyi.iteye.com/blog/1553464

android TextView部分文字可点击 不同大小文字添加背景且居中显示_第1张图片

txt.setText("这是一条测试文本");
        SpannableString clickString = new SpannableString("可点击文本");
        clickString.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                startActivity(new Intent(MainActivity.this, FirstActivity.class));
            }

            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(Color.RED);//设置颜色
            }
        }, 0, clickString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        txt.append(clickString);
        txt.append(new SpannableString("这也是一条测试文本"));
        SpannableString clickString2 = new SpannableString("我是可点击的");
        clickString2.setSpan(new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                startActivity(new Intent(MainActivity.this, SecondActivity.class));
            }

            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);
                ds.setColor(Color.BLUE); //设置颜色
            }
        }, 0, clickString2.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        txt.append(clickString2);
        txt.setMovementMethod(LinkMovementMethod.getInstance());//开始响应点击事件

不同大小文字添加背景且居中显示

参考:
https://www.jianshu.com/p/dd4286389b7e
https://www.jianshu.com/p/d7ffa436d664

要实现的效果如下
android TextView部分文字可点击 不同大小文字添加背景且居中显示_第2张图片
想要实现上图的效果首先想到的是先设置RelativeSizeSpan改变文字大小、再设置BackgroundColorSpan添加背景、再设置ForegroundColorSpan改变活动标签文字大小

SpannableString spannableString = new SpannableString(" 活动标签 " + "我是商品标题我是商品标题我是商品标题我是商品标题我是商品标题");
spannableString.setSpan(new RelativeSizeSpan(0.7f),0,6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new BackgroundColorSpan(Color.RED),0,6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new ForegroundColorSpan(Color.WHITE),0,6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tvSpan.setText(spannableString);

看下结果吧
android TextView部分文字可点击 不同大小文字添加背景且居中显示_第3张图片
发现活动标签的文字没有竖直居中,这里就需要自定义了

/**
 * Created by cys on 2018/11/2 0002.
 * 根据大小绘制对应大小背景span
 */
public class BackgroundColorResizeSpan extends ReplacementSpan {
    private int mBackgroundColor;//字体背景色
    private float fontSizePx;//字体大小单位px
    private int mTextColor;//字体颜色
    private int mWidth;

    public BackgroundColorResizeSpan(int mBackgroundColor, int mTextColor, float fontSizePx) {
        this.mBackgroundColor = mBackgroundColor;
        this.mTextColor = mTextColor;
        this.fontSizePx = fontSizePx;
    }

    @Override
    public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {
        paint.setTextSize(fontSizePx);
        //获取文字宽度
        mWidth = (int) paint.measureText(text.subSequence(start, end).toString());
        return mWidth;
    }

    @Override
    public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
        paint.setTextSize(fontSizePx);
        Paint.FontMetrics fontMetrics = paint.getFontMetrics();
        paint.setColor(mBackgroundColor);
        //绘制背景
        canvas.drawRect(x, (bottom + top) / 2 - (fontMetrics.bottom - fontMetrics.top) / 2, mWidth, (bottom + top) / 2 + (fontMetrics.bottom - fontMetrics.top) / 2, paint);
        paint.setColor(mTextColor);
        //绘制文字
        canvas.drawText(text.subSequence(start, end).toString(), x, (top + bottom)/2 - (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.top, paint);

    }
}

使用起来也是比较方便的

SpannableString spannableString = new SpannableString(" 活动标签 " + "我是商品标题我是商品标题我是商品标题我是商品标题我是商品标题");
spannableString.setSpan(new BackgroundColorResizeSpan(Color.RED, Color.WHITE, spToPx(11)), 0, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tvSpan.setText(spannableString);

运行出来就是第一张图的效果,里面绘制位置的计算主要用到了Paint.FontMetrics类,可参考我另一篇博客 https://blog.csdn.net/SS_S1gn/article/details/80480469 此处不再赘述

textview设置html文本,拦截超链接应用内处理

textView1.setText(Html.fromHtml(htmlLinkText));
        textView1.setMovementMethod(LinkMovementMethod.getInstance());
        CharSequence text = textView1.getText();
        if (text instanceof Spannable) {
            int end = text.length();
            Spannable sp = (Spannable) textView1.getText();
            URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
            SpannableStringBuilder style = new SpannableStringBuilder(text);
            style.clearSpans();// should clear old spans

            //循环把链接发过去
            for (URLSpan url : urls) {
                MyURLSpan myURLSpan = new MyURLSpan(url.getURL());
                style.setSpan(myURLSpan, sp.getSpanStart(url),
                        sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
            }
            textView1.setText(style);
        }
	private class MyURLSpan extends ClickableSpan {

        private String mUrl;

        MyURLSpan(String url) {
            mUrl = url;
        }

        @Override
        public void onClick(View widget) {
            Toast.makeText(MainActivity.this, mUrl, Toast.LENGTH_LONG).show();
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
            ds.setUnderlineText(false);
        }
    }

你可能感兴趣的:(android知识点)