自定义TextView末尾增加高亮文字(ForegroundColorSpan)和点击事件(ClickableSpan)

一、自定义TextView实现增加高亮文字和点击事件
先看效果图如下:
在这里插入图片描述
详细描述是这样的:实现一个文本框,条件1:文本显示三行。条件2:文本超过三行时,在末尾显示省略号,并且在末尾展示“查看全部 >”按钮,高亮显示,并且可以点击跳转界面。条件3:文本三行能全部显示完整,则不展示“查看全部 >”按钮。
这个实现跟可扩展TextView的定义不一样,只需要实现末尾添加文字、图片、高亮、可点击即可。

当然难点是在:“查看全部 >”按钮,精确的显示在文本的最后面。所以计算需要展示的字符串长度,就是重点了。

二、直接看代码吧

class TextViewURLSpan extends ClickableSpan {
        @Override
        public void updateDrawState(TextPaint ds) {
            ds.setColor(Color.RED);
            ds.setUnderlineText(false); //去掉下划线
        }

        @Override
        public void onClick(View widget) {//点击事件
            widget.setSelected(false);
            Toast.makeText( MainActivity.this, "点击了", Toast.LENGTH_SHORT).show();
        }
    }
final String content = "赵丽颖,1987年10月16日出生于河北省廊坊市,中国内地女演员、歌手,河北省旅游形象大使。2006年,因获得《雅虎搜星》比赛冯小刚组冠军而进入演艺圈;同年,在冯小刚执导的广告片《跪族篇》中担任女主角。2011年,因在古装剧《新还珠格格》中饰演晴儿一角而被观众认识。2013年,凭借古装剧《陆贞传奇》获得更多关注。2014年10月,在第10届金鹰电视艺术节举办的投票活动中被选为“金鹰女神”";
        testTextview2 = findViewById(R.id.testTextview2);
        testTextview2.post(new Runnable() {

            @Override
            public void run() {
                //初始化,用于判断字符串是否全部展示出来。
                testTextview2.setText(content);
                //在这里要特别的注意content里面如果有换行符,则获取到的getEllipsisCount不准。
                int ellipsisCount = getEllipsisCount(testTextview2);
                //大于0表示被省略了,0表示全部展示。
                if (ellipsisCount > 0) {
                    //整个字符串长度
                    int length = testTextview2.getText().length();
                    //显示出来的字符串长度(用于截取的坐标)
                    int subStrEnd = length - ellipsisCount;
                    String text = "";

                    for (int i = 0; i < Utils.ADDED_STRING.length() * 2.5; i++) {
                        //防止数组越界
                        if (subStrEnd - i > content.length()) {
                            return;
                        }
                        //截取并添加省略号(注意边界值,刚好为0的情况下), 或者是添加自己需要的文本,如:"…    查看全部   "
                        text = content.subSequence(0, subStrEnd - i) + "";
                        //先设置文本才能获取到下面的数据
                        testTextview2.setText(Utils.setSpanIconWithTextView(MainActivity.this, text, R.mipmap.right_arrow, new TextViewURLSpan()));
                        int _ellipsisCount = getEllipsisCount(testTextview2);
                        //通过for循环来精确的判断我们截取字符串后,加上"…",再加上其它字符后,是否精准全部展示出来,如果刚好展示出来了,就停止循环,按照当前的字符串截取数量展示
                        if (_ellipsisCount <= 0) {
                            //设置使点击事件生效,这段代码不能提前设置,否则会导致三行变成四行,使"查看全部"按钮换行,且第四行全部拥有点击事件。一定要注意
                            testTextview2.setMovementMethod(LinkMovementMethod.getInstance());
                            //设置点击文字后,背景高亮颜色
                            testTextview2.setHighlightColor(Color.TRANSPARENT);
                            break;
                        }
                    }
                } else {
                    testTextview2.setText(content);
                }
            }
        });
package com.migu.recyclerviewtest;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;

/**
 * @author Oliver
 */
public class Utils {

    /**
     * 自己需要添加到文本后的字符串
     */
    public static final String ADDED_STRING= "…    查看全部    ";

    /**
     *
     * @param context
     * @param strContent 截取后的字符串
     * @param resourceId 图片id
     * @return
     */
    public static SpannableStringBuilder setSpanIconWithTextView(Context context, String strContent, int resourceId, MainActivity.TextViewURLSpan clickSpan) {
        if (resourceId == 0) {
            return new SpannableStringBuilder(strContent);
        } else {
            //不判字符串“”空,为了没文字的时候也能显示标签,避免null
            if (strContent == null) {
                strContent = "";
            }
            //添加自己需要的字符串
            strContent = strContent + ADDED_STRING;

            SpannableStringBuilder stringBuilder = new SpannableStringBuilder(strContent);

            //设置改变展示字符串后,哪些字符串需要修改颜色
            ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.RED);
            stringBuilder.setSpan(colorSpan, strContent.length() - 8, strContent.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

            Drawable drawable = context.getResources().getDrawable(resourceId);
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
            CenterImageSpan centerImageSpan = new CenterImageSpan(drawable);
            //把最后一个字符串,夫换成图片,所以我在ALL_STR正常间隔的字符串(2个)后面,多加了一个字符串(共三个空格)
            stringBuilder.setSpan(centerImageSpan, strContent.length() - 1, strContent.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

            //设置哪些字符串需要点击
            stringBuilder.setSpan(clickSpan, strContent.length() - 8, strContent.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

            return stringBuilder;
        }
    }
}

作者:沧水巫云
博客:http://blog.csdn.NET/amir_zt/
以上原创,转载请注明出处,谢谢。
https://blog.csdn.net/amir_zt/article/details/113485113