服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - android TextView中识别多个url并分别点击跳转方法详解

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

2022-10-28 14:00茕&茕 Android

在本篇文章里小编给大家整理的是关于android TextView中识别多个url并分别点击跳转方法详解,需要的朋友们可以学习参考下。

实现方案:

我们直接参考实例代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
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

延伸 · 阅读

精彩推荐