Span的多项点击及TextView去下划线

来源:互联网 发布:58中国网络经纪人app 编辑:程序博客网 时间:2024/05/19 04:50

TextView 上可以设置链接,可以自定义点击事件,但设置多个就比较麻烦了,这里写了个简单的工具方法设置多项点击,并把链接的下划线去掉。


public final class TextHelper {    /**     * 将文字转成连接,可以点击,产生点击事件.     * 定义格式为 [show text],为链接, 点击事件的key为从0开始的链接的次序.     * <br/>     * 如果需要多次添加span,这个应该放在第一个转义.后面再做imageSpan等操作.     *     * @param source  待转义的字符.     * @return     */    public static Spannable getLinkSpan(int color, CharSequence source, WpClickSpan.OnSpanClickListener listener) {        SpannableStringBuilder ssb = new SpannableStringBuilder(source);        // 1. 找到所有的位置.记录下        // 2. 替换掉格式[], 转成要显示的文本        // 3. 添加点击span.添加事件.        Pattern pattern = Pattern.compile("\\[.+?\\]");        final Matcher matcher = pattern.matcher(source);        int offset = 0;        //存放所有的链接起始点和终点位置z        //这里需要注意的是每替换一次会有2个位置的偏移        List<Integer> indexArray = new ArrayList<>();        while (matcher.find()) {            String group = matcher.group();            int start = matcher.start() - offset;            int end = matcher.end() - offset;            //每次移除一对[]都有2个偏移.            ssb.replace(start, end, group.substring(1, group.length() - 1));            indexArray.add(start);            indexArray.add(end - 2);            offset += 2;        }        //indexArray        for (int i = 0; i < indexArray.size(); i += 2) {            int start = indexArray.get(i);            int end = indexArray.get(i + 1);            final WpClickSpan clickSpan = new WpClickSpan(1 + i / 2,color, listener);            ssb.setSpan(clickSpan, start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);        }        return ssb;    }

根据text,获取到span。链接文字要放在中括号里,可以设置链接字的颜色。设置点击是通过自定义的ClickSpan实现的。


public class WpClickSpan extends ClickableSpan implements ParcelableSpan {    private int mKey;//连接key,用于确定唯一的链接点击    private int mColor;    OnSpanClickListener spanClickListener;    public WpClickSpan(int key, int color, OnSpanClickListener spanClickListener) {        this.mKey = key;        mColor = color;        this.spanClickListener = spanClickListener;    }    public void setSpanClickListener(OnSpanClickListener spanClickListener) {        this.spanClickListener = spanClickListener;    }    @Override    public void onClick(View widget) {        if (spanClickListener != null) {            spanClickListener.onClick(widget, mKey);        }    }    @Override    public int getSpanTypeId() {        return 11;//@hide TextUtils.URL_SPAN;    }    public int getSpanTypeIdInternal(){        return 0;    }    @Override    public int describeContents() {        return 0;    }    @Override    public void writeToParcel(Parcel dest, int flags) {        dest.writeInt(mColor);    }    /**     * Makes the text underlined and in the link color.     */    @Override    public void updateDrawState(TextPaint ds) {        ds.setColor(mColor);//        ds.setUnderlineText(true);    }    public interface OnSpanClickListener {        void onClick(View widget, int key);    }}

这里 ds.setUnderlineText(true)就可以加入下划线了。


然后就是使用了:

   Spannable s = TextHelper.getLinkSpan(getResources().getColor(R.color.color_c9), getResources().getString(R.string.nav_has_read), new WpClickSpan.OnSpanClickListener() {                @Override                public void onClick(View widget, int key) {                    if (key == 1) {                     //to do                    } else if (key == 2) {                       // to do                    }                }            });            TextView tv = (TextView) root.findViewById(R.id.nav_text);                    tv.setText(s);            tv.setMovementMethod(LinkMovementMethod.getInstance());


这里要注意两个地方,一个是key是从1开始的,第二个是必须设置setMovementMethod,不然点击事件就没有效果了。

0 0
原创粉丝点击