最近在寫案子的時候遇到一個需求, 希望 textView 能夠偵測 http:// 並且判斷該url為何,並根據不同的url做不同的動作,假設只需要判斷 hyperlink 使用 textview 內建的android:autolink就可以完成,但是內建的textView並不能偵測click的動作,所有的hyperlink都會自動導向browser ,這並符合我們的需求,經過了一段時間的尋找,總算找到了解法,在這邊跟大家分享。
使用的原理
由於 textview 可以使用 SpannableString 然而 SpannableString 有個method 叫 setSpan ,而setSpan的
第一個參數可以傳各式各樣的Span,其中有一個叫做 ClickableSpan ,使用這個span讓我們可以接收到click event, 但是要使hyperlink可以點擊還必須多做一道手續,setMoveMentMethod 在設定完成之後,我們的功能就算大功告成了。
程式碼範例
public void seTextLinkClickListener(TextLinkClickListener listener)
{
mListener = listener;
MovementMethod m = getMovementMethod();
if ((m == null) || !(m instanceof LinkMovementMethod)) {
if (getLinksClickable()) {
setMovementMethod(LinkMovementMethod.getInstance());
}
}
}
public void GenerateLink(String text)
{
SpannableString linkableText = new SpannableString(text);
gatherLinks(listOfLinks, linkableText, hyperLinksPattern);
for(int i = 0; i< listOfLinks.size(); i++)
{
Hyperlink linkSpec = listOfLinks.get(i);
linkableText.setSpan(linkSpec.span, linkSpec.start, linkSpec.end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
setText(linkableText);
}
private final void gatherLinks(ArrayList<Hyperlink> links, Spannable s,
Pattern pattern) {
Matcher m = pattern.matcher(s);
while (m.find()) {
int start = m.start();
int end = m.end();
Hyperlink spec = new Hyperlink();
spec.textSpan = s.subSequence(start, end);
spec.span = new InternalURLSpan(spec.textSpan.toString());
spec.start = start;
spec.end = end;
links.add(spec);
}
}
public class InternalURLSpan extends ClickableSpan
{
private String clickedSpan;
public InternalURLSpan (String clickedString)
{
clickedSpan = clickedString;
}
@Override
public void onClick(View textView)
{
mListener.onTextLinkClick(textView, clickedSpan);
}
}
class Hyperlink
{
CharSequence textSpan;
InternalURLSpan span;
int start;
int end;
}
接著只需要再mainActivity裡面使用這個檔案就可以了
附上 sample code
網路上也有相關的Git Project
沒有留言:
張貼留言