欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

android TextView中识别多个url并分别点击跳转方法详解

程序员文章站 2022-07-06 16:51:19
实现方案: 我们直接参考实例代码: private string pattern = "((http|ftp|https)://)(([a-za-z0...

实现方案:

我们直接参考实例代码:

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

以上实例代码大家可以测试下,感谢大家的学习和对的支持。