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;    }}


原文地址:https://www.cnblogs.com/wangqiong/p/11412269.html

时间: 2024-08-29 02:31:49

android TextView中识别多个url并分别点击跳转的相关文章

Android TextView中实现点击文本超链接(无下划线)的封装类

android中有的时候须要在TextView上设置一些超链接,点击这些超链接时进行一些操作.比如新浪微博上的一些keyword,点击时会跳转到对应的页面. 怎样实现我们就直接看源代码吧. /** * * created by Mr.Simple, Aug 21, 20141:51:40 PM. * Copyright (c) 2014, hehonghui@umeng.com All Rights Reserved. * * ##################################

Android TextView中文字通过SpannableString来设置超链接、颜色、字体等属

在Android中,TextView是我们最常用的用来显示文本的控件. 一般情况下,TextView中的文本都是一个样式.那么如何对于TextView中各个部分的文本来设置字体,大小,颜色,样式,以及超级链接等属性呢?下面我们通过SpannableString的具体实例操作来演示一下. res-layout-main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:and

Android TextView中展示含有html标签的文字

两个小实例: 1.服务端返回的带有html标签的文字,在textview中展示的时候,能正确的换行. 2.需要展示的下载的超链接,以文字代替,隐藏下载地址: 实现效果如下: 代码如下: package com.android.study; import android.app.Activity; import android.os.Bundle; import android.text.Html; import android.text.method.LinkMovementMethod; im

Android TextView中文字设置超链接、颜色、字体

TextView是用来显示文本的,有时需要给TextView中的个别字设置为超链接,或者设置个别字的颜色.字体等,那就需要用到Spannable对象,可以借助Spannable对象实现以上设置. 效果图: Activity代码: import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.text.Spannable; import android.tex

(转)Android TextView中文字通过SpannableString来设置超链接、颜色、字体等属性以及自定义链接到下一个Activity

在Android中,TextView是我们最常用的用来显示文本的控件. 一般情况下,TextView中的文本都是一个样式.那么如何对于TextView中各个部分的文本来设置字体,大小,颜色,样式,以及超级链接等属性呢?下面我们通过SpannableString的具体实例操作来演示一下. res-layout-main.xml 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns

(四十八)Android TextView中文字通过SpannableString来设置超链接、颜色、字体等属性

1.程序结构图 2.MainActivity.java中的代码 package com.example.setlinkdemo; import java.io.IOException; import org.xmlpull.v1.XmlPullParserException; import android.app.Activity; import android.content.Intent; import android.content.res.ColorStateList; import a

android textview 中部分内容 颜色 样式 点击事件的设置

// 文本内容 SpannableString ss = new SpannableString(remindtitle); int stringlength = ss.length(); // 设置0-2的字符颜色 ss.setSpan(new ForegroundColorSpan(Color.RED), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); // 设置2-5的字符链接到电话簿,点击时触发拨号 ss.setSpan(new URLSpan("tel

Android TextView中链接(link)点击事件的截取

布局文件xml 1 <TextView 2 android:layout_width="match_parent"3 android:layout_height="match_parent"4 android:id="@+id/test_note"5 android:autoLink="all"6 /> 这里autoLink="all"就是链接所有类型的,包括网址,电话,邮件地址什么的. Jav

Android textView中划线

String string = "市场价:¥158.00"; TextView textView = (TextView) findViewById(R.id.textView); SpannableString sp = new SpannableString(string); sp.setSpan(new StrikethroughSpan(), 0, string.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); textView.setT