package net.oschina.gitapp.widget;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.XMLReader;
import net.oschina.gitapp.bean.URLs;
import net.oschina.gitapp.common.StringUtils;
import net.oschina.gitapp.common.UIHelper;
import android.content.Context;
import android.graphics.Color;
import android.text.Editable;
import android.text.Html;
import android.text.Html.TagHandler;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
/**
* 超链接文本控件
*
* @author liux (http://my.oschina.net/liux)
* @version 1.0
* @created 2012-3-21
*/
public class LinkView extends TextView {
private OnLinkClickListener mLinkClickListener = new LinkView.OnLinkClickListener() {
@Override
public void onLinkClick() {
}
};
public LinkView(Context context) {
super(context);
}
public LinkView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LinkView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public OnLinkClickListener getLinkClickListener() {
return mLinkClickListener;
}
public void setLinkClickListener(OnLinkClickListener linkClickListener) {
this.mLinkClickListener = linkClickListener;
}
public final static Pattern WECHAT_REG = Pattern.compile("(<{1}img[\\s]+class=\"wechat-emoji\"[\\s]+src=\"[^<]+\"[\\s]+alt=\"([^<\\s\"]+)\"[\\s]+[^<]*[>]{1})");
private static String filterWechat(String linktxt) {
System.out.println(linktxt);
if (null == linktxt)
return "";
try {
Matcher match = WECHAT_REG.matcher(linktxt);
if (null == match)
return linktxt;
while (match.find()) {
String target = match.group(1);
String rp = match.group(2);
linktxt = linktxt.replace(target, "[" + rp + "]");
}
} catch (Exception e) {
return linktxt;
}
return linktxt;
}
public void setLinkText(String linktxt) {
linktxt = filterWechat(linktxt);
Spanned span = Html.fromHtml(linktxt);
setText(span);
setMovementMethod(LinkMovementMethod.getInstance());
parseLinkText(span);
}
public void parseLinkText(Spanned spanhtml) {
CharSequence text = getText();
if (text instanceof Spannable) {
int end = text.length();
Spannable sp = (Spannable) getText();
URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
URLSpan[] htmlurls = spanhtml != null ? spanhtml.getSpans(0, end,
URLSpan.class) : new URLSpan[] {};
if (urls.length == 0 && htmlurls.length == 0)
return;
SpannableStringBuilder style = new SpannableStringBuilder(text);
// style.clearSpans();// 这里会清除之前所有的样式
for (URLSpan url : urls) {
if (!isNormalUrl(url)) {
style.removeSpan(url);// 只需要移除之前的URL样式,再重新设置
NoLinkSpan span = new NoLinkSpan(url.getURL());
style.setSpan(span, sp.getSpanStart(url),
sp.getSpanEnd(url),
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
continue;
}
style.removeSpan(url);// 只需要移除之前的URL样式,再重新设置
MyURLSpan myURLSpan = new MyURLSpan(url.getURL());
style.setSpan(myURLSpan, sp.getSpanStart(url),
sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
for (URLSpan url : htmlurls) {
style.removeSpan(url);// 只需要移除之前的URL样式,再重新设置
MyURLSpan myURLSpan = new MyURLSpan(url.getURL());
style.setSpan(myURLSpan, spanhtml.getSpanStart(url),
spanhtml.getSpanEnd(url),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
setText(style);
}
}
public void parseLinkText() {
parseLinkText(null);
}
public class MyURLSpan extends ClickableSpan {
private String mUrl;
public MyURLSpan(String url) {
mUrl = url;
}
@Override
public void onClick(View widget) {
mLinkClickListener.onLinkClick();
/*URLs urls = URLs.parseURL(mUrl);
if (urls != null) {
UIHelper.showLinkRedirect(widget.getContext(),
urls.getObjType(), urls.getObjId(), urls.getObjKey());
} else {
UIHelper.openBrowser(widget.getContext(), mUrl);
}*/
}
}
/**
* 无响应的ClickableSpan
*
* @author yeguozhong@yeah.net
*
*/
public class NoLinkSpan extends ClickableSpan {
private String text;
public NoLinkSpan(String text) {
super();
this.text = text;
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setColor(Color.BLACK);
ds.setUnderlineText(false); // 去掉下划线
}
@Override
public void onClick(View widget) {
// doNothing...
}
}
public interface OnLinkClickListener {
void onLinkClick();
}
/**
* 过滤掉一些不正常的链接
*
* @param url
* @return
*/
public boolean isNormalUrl(URLSpan url) {
String urlStr = url.getURL();
if (urlStr.endsWith(".sh")) {
return false;
}
return true;
}
}