在
handle hyperlink in textView(一) 中有提到如何使 textview 能夠處理url 使之能夠被點擊。
但是如果僅使用那邊的寫法,當將這個textview放到 listview內會造成 itemclick無法被點擊的問題。
為何會造成這個問題?
由於設定 setmovementmethod會同時
- setFocusable(true);
- setClickable(true);
- setLongClickable(true);
簡單的說就是 Event 都被 Textview處理掉了,所以listview拿不到itemclick event。
所以我們必須客製化touch event,只有在url被點擊的時候,才使用Textview去處理,其他時候就將event 往下傳遞。
首先要稍微提一下 onTouchEvent的 override
return true 代表這個事件在這邊被處理,所以不會再往下傳遞。
return false 代表事件並未被處理,會繼續向下傳遞。
首先先客製化 LinkMovementMethod 只有在url 被點擊時才處理 (return true)
public static class LocalLinkMovementMethod extends LinkMovementMethod{
static LocalLinkMovementMethod sInstance;
public static LocalLinkMovementMethod getInstance() {
if (sInstance == null)
sInstance = new LocalLinkMovementMethod();
return sInstance;
}
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_UP ||
action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
if (action == MotionEvent.ACTION_UP) {
link[0].onClick(widget);
} else if (action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer,
buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]));
}
if (widget instanceof LinkEnabledTextView){
((LinkEnabledTextView) widget).linkHit = true;
}
return true;
} else {
Selection.removeSelection(buffer);
Touch.onTouchEvent(widget, buffer, event);
return false;
}
}
return Touch.onTouchEvent(widget, buffer, event);
}
}
接著在客製化的 textView 裡面 override touchevent 和 focus
@Override
public boolean hasFocusable() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
linkHit = false;
boolean res = super.onTouchEvent(event);
if (dontConsumeNonUrlClicks)
return linkHit;
return res;
}
經過這樣的修改,listview的onitemclick event就不會再被textview吃掉了。