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í)和對(duì)腳本之家的支持。
- 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)注冊(cè)界面功能示例
- 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開發(fā)之ClipboardManager剪貼板功能示例
這篇文章主要介紹了Android開發(fā)之ClipboardManager剪貼板功能,結(jié)合簡單實(shí)例形式分析了Android使用ClipboardManager實(shí)現(xiàn)剪貼板功能的相關(guān)操作技巧,需要的朋友可以參考下2017-03-03
Android 雙進(jìn)程守護(hù)的實(shí)現(xiàn)代碼
這篇文章主要介紹了Android 雙進(jìn)程守護(hù)的實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08
Android中實(shí)現(xiàn)在矩形框中輸入文字顯示剩余字?jǐn)?shù)的功能
在矩形輸入框框中輸入文字顯示剩余字?jǐn)?shù)的功能在app開發(fā)中經(jīng)常會(huì)見到,今天小編就通過實(shí)例代碼給大家分享android實(shí)現(xiàn)輸入框提示剩余字?jǐn)?shù)功能,代碼簡單易懂,需要的朋友參考下吧2017-04-04
Android獲取驗(yàn)證碼倒計(jì)時(shí)顯示效果
這篇文章主要為大家詳細(xì)介紹了Android獲取驗(yàn)證碼顯示的兩種簡單實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10
Android Studio實(shí)現(xiàn)仿微信APP門戶界面詳解及源碼
這篇文章帶你通過Android studio來實(shí)現(xiàn)微信APP的門戶界面,主要說明框架的各部分功能與實(shí)現(xiàn)過程,下文包含了整個(gè)開發(fā)過程,以及解決問題的思路并再末尾提供了源碼鏈接2021-10-10
簡單了解Android性能優(yōu)化方向及相關(guān)工具
這篇文章主要介紹了簡單了解Android性能優(yōu)化方向及相關(guān)工具,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
Android Intent實(shí)現(xiàn)頁面跳轉(zhuǎn)的方法示例
本篇文章主要介紹了Android Intent實(shí)現(xiàn)頁面跳轉(zhuǎn)的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-03-03

