android TextView中识别多个url并分别点击跳转
Posted wangqiong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android TextView中识别多个url并分别点击跳转相关的知识,希望对你有一定的参考价值。
实现方案:
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;
mTv.setText(identifyUrl(richURL.msg));
public SpannableStringBuilderForAllvers identifyUrl(CharSequence text)
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 < clickableSpans.length; 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())
//得到网址数m.group()
if (m.start() < m.end())
span.setSpan(new LinkClickSpan(m.group(), m.group(), mUrlSpanClickListener),
m.start(), m.end(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
return span;
private static final String HTTPS = "https://";
private static final String HTTP = "http://";
private static final String FTP = "ftp://";
public static boolean hasNetUrlHead(String url)
return (!TextUtils.isEmpty(url)) && (url.startsWith(HTTP) || url.startsWith(HTTPS) || url.startsWith(FTP));
private UrlSpanClickListener mUrlSpanClickListener = new UrlSpanClickListener()
@Override
public void onClick(View view, String url, String content)
if (TextUtils.isEmpty(url))
return;
Matcher url_matcher = Patterns.WEB_URL.matcher(url);
if (url_matcher.matches())
String tempUrl;
if (hasNetUrlHead(url))
tempUrl = url;
else
tempUrl = HTTPS + url;
//通过webview打开相应的url
//Bundle bundle = new Bundle();
//bundle.putString(WebCordovaBaseFragment.EXTRA_URL, tempUrl);
//bundle.putBoolean(WebCordovaBaseFragment.ENABLE_WEB_TITLE, true);
//WebViewActivity.presentWeb(Utilities.getApplicationContext(), WebViewActivity.class, WebCommonFragment.class, content, bundle);
;
public interface UrlSpanClickListener
void onClick(View view, String url, String content);
public static class LinkClickSpan extends ClickableSpan
private int mColor = Utilities.getApplicationContext().getResources().getColor(R.color.yc_color_007AFF_CBN);
private String mUrl;
private String mContent;
UrlSpanClickListener mClickListener;
public LinkClickSpan(String url, String content, UrlSpanClickListener onClickListener)
super();
mUrl = url;
mContent = content;
mClickListener = onClickListener;
@Override
public void updateDrawState(TextPaint ds)
ds.setColor(mColor);
ds.linkColor = mColor;
ds.setUnderlineText(true);//设置是否下划线
ds.clearShadowLayer();
@Override
public void onClick(View widget)
if (mClickListener != null)
mClickListener.onClick(widget, mUrl, mContent);
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;
public class ClickableSpanTextView extends AppCompatTextView
private BackgroundColorSpan backgroundColorSpan;
private boolean hasSpan;
public ClickableSpanTextView(Context context)
super(context);
init();
public ClickableSpanTextView(Context context, AttributeSet attrs)
super(context, attrs);
init();
public ClickableSpanTextView(Context context, AttributeSet attrs, int defStyleAttr)
super(context, attrs, defStyleAttr);
init();
private void init()
setMovementMethod(LinkMovementMethod.getInstance());
backgroundColorSpan = new BackgroundColorSpan(getContext().getResources().getColor(R.color.yc_color_4B4B4B_CDG));
@Override
public boolean onTouchEvent(MotionEvent event)
boolean handled = super.onTouchEvent(event);
int action = event.getAction();
if (!(getText() instanceof Spannable))
return handled;
Spannable spannable = (Spannable) getText();
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN)
int x = (int) event.getX();
int y = (int) event.getY();
x -= getTotalPaddingLeft();
y -= getTotalPaddingTop();
x += getScrollX();
y += getScrollY();
Layout layout = getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
if (off >= getText().length())
int off1 = layout.getOffsetForHorizontal(line, x - getTextSize());
if (off == off1)
return handled;
ClickableSpan[] links = spannable.getSpans(off, off, ClickableSpan.class);
if (links.length > 0)
ClickableSpan clickableSpan = links[0];
int start = spannable.getSpanStart(clickableSpan);
int end = spannable.getSpanEnd(clickableSpan);
if (action == MotionEvent.ACTION_DOWN && !hasSpan)
spannable.setSpan(backgroundColorSpan, start, end, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
hasSpan = true;
else if (hasSpan)
spannable.removeSpan(backgroundColorSpan);
hasSpan = false;
return links.length != 0;
else
if (hasSpan && action != MotionEvent.ACTION_MOVE)
spannable.removeSpan(backgroundColorSpan);
hasSpan = false;
return handled;
以上是关于android TextView中识别多个url并分别点击跳转的主要内容,如果未能解决你的问题,请参考以下文章
Android:将 onClickListener 设置为 TextView 中的部分文本 - 问题
Android:如何使用 dataBinding 在同一个 TextView 中显示多个值?
有没有办法让 WebView 在 Android 中自动链接 URL 和电话号码?