android getspans,android TextView中识别url

一、需求

1、在TextView中识别url;

2、能识别出非http://|https://|ftp://等协议开头的非标准url

3、对url设置颜色、下划线、点击等等

二、方案

LinkedList mStringList = new LinkedList();

LinkedList mUrlInfos = new LinkedList();

private String pattern =

"((http|ftp|https)://)(([a-zA-Z0-9\\._-]+\\.[a-zA-Z]{2,6})|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(:[0-9]{1,4})*(/[a-zA-Z0-9\\&%_\\./-~-]*)?|(([a-zA-Z0-9\\._-]+\\.[a-zA-Z]{2,6})|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(:[0-9]{1,4})*(/[a-zA-Z0-9\\&%_\\./-~-]*)?";

Pattern r = Pattern.compile(pattern);

Matcher m;

int flag= Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;

class UrlInfo {

public int start;

public int end;

}

public SpannableStringBuilderForAllvers identifyUrl(CharSequence text) {

mStringList.clear();

mUrlInfos.clear();

CharSequence contextText;

CharSequence clickText;

text = text == null ? "" : text;

//以下用于拼接本来存在的spanText

SpannableStringBuilderForAllvers span = new SpannableStringBuilderForAllvers(text);

ClickableSpan[] clickableSpans = span.getSpans(0, text.length(), ClickableSpan.class);

if (clickableSpans.length > 0) {

int start=0;

int end=0;

for (int i=0;i

start=span.getSpanStart(clickableSpans[0]);

end=span.getSpanEnd(clickableSpans[i]);

}

//可点击文本后面的内容页

contextText = text.subSequence(end, text.length());

//可点击文本

clickText = text.subSequence(start,

end);

} else {

contextText = text;

clickText = null;

}

m = r.matcher(contextText);

//匹配成功

while (m.find()) {

//得到网址数

UrlInfo info = new UrlInfo();

info.start = m.start();

info.end = m.end();

mStringList.add(m.group());

mUrlInfos.add(info);

}

return joinText(clickText, contextText);

}

/** 拼接文本 */

private SpannableStringBuilderForAllvers joinText(CharSequence clickSpanText,

CharSequence contentText) {

SpannableStringBuilderForAllvers spanBuilder;

if (clickSpanText != null) {

spanBuilder = new SpannableStringBuilderForAllvers(clickSpanText);

} else {

spanBuilder = new SpannableStringBuilderForAllvers();

}

if (mStringList.size() > 0) {

//只有一个网址

if (mStringList.size() == 1) {

String preStr = contentText.toString().substring(0, mUrlInfos.get(0).start);

spanBuilder.append(preStr);

String url = mStringList.get(0);

int start = spanBuilder.length();

spanBuilder.append(url, new UnderlineSpan(), flag);

int end = spanBuilder.length();

if (start >= 0 && end > 0 && end > start) {

spanBuilder.setSpan(new ForegroundColorSpan(Color.BLUE), start, end, flag);

}

String nextStr = contentText.toString().substring(mUrlInfos.get(0).end);

spanBuilder.append(nextStr);

} else {

//有多个网址

for (int i = 0; i < mStringList.size(); i++) {

if (i == 0) {

//拼接第1个span的前面文本

String headStr =

contentText.toString().substring(0, mUrlInfos.get(0).start);

spanBuilder.append(headStr);

}

if (i == mStringList.size() - 1) {

//拼接最后一个span的后面的文本

int start = spanBuilder.length();

spanBuilder.append(mStringList.get(i), new UnderlineSpan(),

flag);

int end = spanBuilder.length();

if (start >= 0 && end > 0 && end > start) {

spanBuilder.setSpan(new ForegroundColorSpan(Color.BLUE), start, end, flag);

}

String footStr = contentText.toString().substring(mUrlInfos.get(i).end);

spanBuilder.append(footStr);

}

if (i != mStringList.size() - 1) {

//拼接两两span之间的文本

int start = spanBuilder.length();

spanBuilder.append(mStringList.get(i), new UnderlineSpan(), flag);

int end = spanBuilder.length();

if (start >= 0 && end > 0 && end > start) {

spanBuilder.setSpan(new ForegroundColorSpan(Color.BLUE), start, end, flag);

}

String betweenStr = contentText.toString()

.substring(mUrlInfos.get(i).end,

mUrlInfos.get(i + 1).start);

spanBuilder.append(betweenStr);

}

}

}

} else {

spanBuilder.append(contentText);

}

return spanBuilder;

}

public class SpannableStringBuilderForAllvers extends SpannableStringBuilder{

public SpannableStringBuilderForAllvers() {

super("");

}

public SpannableStringBuilderForAllvers(CharSequence text) {

super(text, 0, text.length());

}

public SpannableStringBuilderForAllvers(CharSequence text, int start, int end){

super(text,start,end);

}

@Override

public SpannableStringBuilder append(CharSequence text) {

if (text == null) {

return this;

}

int length = length();

return (SpannableStringBuilderForAllvers)replace(length, length, text, 0, text.length());

}

/**该方法在原API里面只支持API21或者以上,这里适应低版本*/

public SpannableStringBuilderForAllvers append(CharSequence text, Object what, int flags) {

if (text == null) {

return this;

}

int start = length();

append(text);

setSpan(what, start, length(), flags);

return this;

}

}

标签:end,spanBuilder,url,text,length,start,int,android,TextView

来源: https://www.cnblogs.com/wangqiong/p/10756752.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值