android TextView中識(shí)別多個(gè)url并分別點(diǎn)擊跳轉(zhuǎn)方法詳解
實(shí)現(xiàn)方案:
我們直接參考實(shí)例代碼:
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]); } //可點(diǎn)擊文本后面的內(nèi)容頁 contextText = text.subSequence(end, text.length()); //可點(diǎn)擊文本 clickText = text.subSequence(start, end); } else { contextText = text; clickText = null; } m = r.matcher(contextText); //匹配成功 while (m.find()) { //得到網(wǎng)址數(shù)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打開相應(yīng)的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);//設(shè)置是否下劃線 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或者以上,這里適應(yīng)低版本*/ 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; } }
以上實(shí)例代碼大家可以測試下,感謝大家的學(xué)習(xí)和對腳本之家的支持。
- Android文本視圖TextView實(shí)現(xiàn)跑馬燈效果
- Android文本視圖TextView實(shí)現(xiàn)聊天室效果
- Android使用TypeFace設(shè)置TextView的文字字體
- Flutter中嵌入Android 原生TextView實(shí)例教程
- android使用TextView實(shí)現(xiàn)跑馬燈效果
- Android開發(fā)實(shí)現(xiàn)TextView超鏈接5種方式源碼實(shí)例
- Android開發(fā)中TextView各種常見使用方法小結(jié)
- Android開發(fā)之TextView使用intent傳遞信息,實(shí)現(xiàn)注冊界面功能示例
- Android使用AutoCompleteTextView實(shí)現(xiàn)自動(dòng)填充功能的案例
- Android為textView設(shè)置setText的時(shí)候報(bào)錯(cuò)的講解方案
- 詳解Android TextView屬性ellipsize多行失效的解決思路
- 在Android TextView中顯示圖片的4種方式詳解
- Android實(shí)現(xiàn)梯形TextView效果
相關(guān)文章
Android如何實(shí)現(xiàn)一個(gè)DocumentProvider示例詳解
這篇文章主要為大家介紹了Android如何實(shí)現(xiàn)一個(gè)DocumentProvider示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12Handler實(shí)現(xiàn)線程之間的通信下載文件動(dòng)態(tài)更新進(jìn)度條
每一個(gè)線程對應(yīng)一個(gè)消息隊(duì)列MessageQueue,實(shí)現(xiàn)線程之間的通信,可通過Handler對象將數(shù)據(jù)裝進(jìn)Message中,再將消息加入消息隊(duì)列,而后線程會(huì)依次處理消息隊(duì)列中的消息。這篇文章主要介紹了Handler實(shí)現(xiàn)線程之間的通信下載文件動(dòng)態(tài)更新進(jìn)度條,需要的朋友可以參考下2017-08-08Android為按鈕控件綁定事件的五種實(shí)現(xiàn)方式
本篇文章主要是介紹了Android為按鈕控件綁定事件的五種實(shí)現(xiàn)方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2016-11-11Flutter開發(fā)實(shí)現(xiàn)底部留言板
這篇文章主要為大家詳細(xì)介紹了Flutter開發(fā)實(shí)現(xiàn)底部留言板,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03Android開發(fā)基于ScrollView實(shí)現(xiàn)的漸變導(dǎo)航欄效果示例
這篇文章主要介紹了Android開發(fā)基于ScrollView實(shí)現(xiàn)的漸變導(dǎo)航欄效果,涉及ScrollView事件響應(yīng)及元素屬性動(dòng)態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-12-12Android ActionBar完全解析使用官方推薦的最佳導(dǎo)航欄(上)
Action Bar是一種新増的導(dǎo)航欄功能,在Android 3.0之后加入到系統(tǒng)的API當(dāng)中,它標(biāo)識(shí)了用戶當(dāng)前操作界面的位置,并提供了額外的用戶動(dòng)作、界面導(dǎo)航等功能2017-04-04Android開發(fā)之無痕過渡下拉刷新控件的實(shí)現(xiàn)思路詳解
下拉刷新效果功能在程序開發(fā)中經(jīng)常會(huì)見到,今天小編抽時(shí)間給大家分享Android開發(fā)之無痕過渡下拉刷新控件的實(shí)現(xiàn)思路詳解,需要的朋友參考下吧2016-11-11Android如何實(shí)現(xiàn)設(shè)備的異顯功能詳解
這篇文章主要給大家介紹了關(guān)于Android如何實(shí)現(xiàn)設(shè)備的異顯功能的相關(guān)資料,這篇文章通過示例代碼介紹的非常詳細(xì),對各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-02-02Android中 TeaScreenPopupWindow多類型篩選彈框功能的實(shí)例代碼
這篇文章主要介紹了Android TeaScreenPopupWindow多類型篩選彈框功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-06-06