TextView的富文本帶來了很多便利,但也帶了不少坑,本篇主要解決設置了ClickableSpan、OnClickListener、OnLongClickListener帶來的問題。
我們先來看ClickableSpan、OnClickListener的坑,我們會發現,我們點擊的是Span部分,ClickableSpan的onClick會被執行,但OnClickListener也會執行onClick方法,是不是很刺激啊,其實最好的辦法是在ClickableSpan的onClick被執行時,不要執行OnClickListener也會執行onClick方法的方法就行了(哈哈,那不是廢話嗎)
所以,我們自定義OnTouchListener監聽TextView的事件,來攔截Touch自行處理行爲:
public class CustomTextViewTouchListener implements View.OnTouchListener {
private View.OnClickListener mOnClickListener;
public CustomTextViewTouchListener(View.OnClickListener onClickListener) {
mOnClickListener = onClickListener;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
TextView tv = (TextView) v;
CharSequence text = tv.getText();
if (action == MotionEvent.ACTION_UP) {
if (text instanceof Spanned) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= tv.getTotalPaddingLeft();
y -= tv.getTotalPaddingTop();
x += tv.getScrollX();
y += tv.getScrollY();
Layout layout = tv.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
ClickableSpan[] link = ((Spanned) text).getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
link[0].onClick(tv);
} else {
//do textview click event
if (null != mOnClickListener) {
mOnClickListener.onClick(v);
}
}
} else {
if (null != mOnClickListener) {
mOnClickListener.onClick(v);
}
}
}
return true;
}
}
這樣我們就解決了ClickableSpan、OnClickListener會一起執行的問題,但是這樣的話,我們給TextView設置了長按事件OnLongClickListener就沒辦法工作了,所以我們還需在原來的代碼上做個修改,如下:
public class CustomTextViewTouchListener implements View.OnTouchListener {
private View.OnClickListener mOnClickListener;
private View.OnLongClickListener mOnLongClickListener;
private long mLastActionDownTime = -1;
public CommentTextViewTouchListener(View.OnClickListener onClickListener, View.OnLongClickListener onLongClickListener) {
mOnClickListener = onClickListener;
mOnLongClickListener = onLongClickListener;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
TextView tv = (TextView) v;
CharSequence text = tv.getText();
if (action == MotionEvent.ACTION_DOWN) {
mLastActionDownTime = System.currentTimeMillis();
} else {
long actionUpTime = System.currentTimeMillis();
if (actionUpTime - mLastActionDownTime >= ViewConfiguration.getLongPressTimeout() && null != mOnLongClickListener) {
mOnLongClickListener.onLongClick(v);
return false;
}
if (action == MotionEvent.ACTION_UP) {
if (text instanceof Spanned) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= tv.getTotalPaddingLeft();
y -= tv.getTotalPaddingTop();
x += tv.getScrollX();
y += tv.getScrollY();
Layout layout = tv.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
ClickableSpan[] link = ((Spanned) text).getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
link[0].onClick(tv);
} else {
//do textview click event
if (null != mOnClickListener) {
mOnClickListener.onClick(v);
}
}
} else {
if (null != mOnClickListener) {
mOnClickListener.onClick(v);
}
}
}
}
return true;
}
}
完美解決…