这个项目是什么

TextView 支持 Spannable,但真用起来,一个页面往往要写一堆 setSpan、ClickableSpan、ImageSpan 的样板代码:给某段文字加颜色、下划线,让某几个字可点击,在文字中间插一张图,文字太长时缩略显示或者跑马灯。SpanTextView 把这些局部操作收进一个 TextView 子类,调用从一堆 View 操作变成一行。

按 README 的说法,如果不做这层封装,这些代码都得堆在 Activity 里。

能做什么

README 里的操作大致分几类:

  • 局部点击:给指定文字设置点击事件,回调里带 text、position 和 sign 标识
  • 局部格式:字号、颜色、背景色、圆角背景、下划线
  • 图片:在最前面、中间、最后插入图片,把某段文字替换成图片,图片也可以带点击回调
  • 跑马灯:setMarquee(true) 开启,可设置重复次数
  • 清除:按设置时返回的对象清除单个 span,或者 clearAllSpan() 全部清除

用 sign 字符串把设置和回调对应起来,是这套 API 的关键设计。设置时给一个标识,点击回调里原样带回来,不用靠位置去猜点的是哪一个。图片的点击回调也是同样的思路,onImageLinkClick 里拿到 position 和 sign。

使用方法

设置局部点击:

// 设置点击事件
tvTest.setSpanLink("链接1", SIGN_ONE, false, Color.GREEN);
tvTest.setSpanLink("链接2", SIGN_TWO, false);
tvTest.setSpanLink("链接3", SIGN_THREE);

// 点击事件回调
tvTest.setOnTextLinkClickListener(new SpanTextView.onTextLinkClickListener() {
    @Override
    public void onTextLinkClick(View view, String text, int position, String sign) {
        // 根据 sign 区分点的是哪一个
    }
});

插入和替换图片:

// 添加图片到最前面
tvTest.addImageToFirst(R.drawable.one, SpanTextView.TEXT_SIZE);

// 添加图片到中间("中间添加"的后面)
tvTest.setImage(R.drawable.two, "中间添加", SpanTextView.AFTER_IMAGE);

// 添加图片到最后面
tvTest.addImageToLast(R.drawable.four);

// 替换文本为图片
tvTest.replaceTextToImage("图片标识", R.drawable.three);

带点击的图片,在方法最后多传一个标识字符串,再监听 onImageLinkClickListener;回调里还能用 replaceImageSpan 把图片换成另一张。

格式类操作同样是按文字内容定位:

tvTest.setSpanTextSize("大小", 30);
tvTest.setSpanTextBack("普通背景", Color.BLUE);
tvTest.setSpanTextBack("圆角背景", Color.GREEN, 10);
tvTest.setSpanTextColor("颜色", Color.RED);
tvTest.setUnderLine("下划线", true);

踩坑与思考

README 末尾写「还有其他的功能,具体请查看源码方法」,说明文档没有覆盖全部方法,接入前最好过一遍源码。

这类封装最容易出问题的地方是文本变化之后 span 的位置失效:文字一改,按位置设置的 span 就对不上了。SpanTextView 的接口大多用文字内容或 sign 来定位,而不是直接传下标,用起来会稳一些,但也意味着同一段文字出现多次时要留意到底匹配到的是哪一处。

仓库地址:tpnet/SpanTextView