问题是,如果我对textView进行Linkify处理,则底层的ScrollView不会监听我设置的滑动手势。有没有一种方法可以使文本链接化而不会影响底层视图的手势?
我尝试重写ontouchEvent并返回false到ACTION_MOVE,但ScrollView的手势需要ACTION_DOWN和ACTION_UP事件才能正常工作。有没有实现这一点的方法?
Linkify
应用于textView的movementMethod LinkMovementMethod
。虽然该movement方法实现了一种垂直滚动方法,但它会覆盖父级具有的任何其他滚动方法。虽然touchEvent
可以分派到父级,但特定的父级ScrollView
需要整个序列ACTION_DOWN
,ACTION_MOVE
,ACTION_UP
来执行(扫描检测)。
因此,我问题的解决方案是在Linkify后删除textView的滚动方法,并在textView的onTouchEvent中处理链接检测操作。
@override
public boolean onTouchEvent(MotionEvent event) {
TextView widget = (TextView) this;
Object text = widget.getText();
if (text instanceof Spanned) {
Spannable buffer = (Spannable) text;
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]));
}
return true;
}
}
}
return false;
}
这样我就可以检测到 Link_Click(仅在用户触摸链接而不是整个 TextView 时执行),并且不需要整个 LinkMovementMethod。@weakwire和@Ridicully的答案是正确的。我刚刚创建了一个小的gist,你可以在你的项目中重新使用它。
这是链接:https://gist.github.com/amilcar-andrade/e4b76840da1dc92febfc
有一件小事情,就是TextView::setText(...)方法使用了autoLink标志,
if (mAutoLinkMask != 0) {
Spannable s2;
if (type == BufferType.EDITABLE || text instanceof Spannable) {
s2 = (Spannable) text;
} else {
s2 = mSpannableFactory.newSpannable(text);
}
if (Linkify.addLinks(s2, mAutoLinkMask)) {
text = s2;
type = (type == BufferType.EDITABLE) ? BufferType.EDITABLE : BufferType.SPANNABLE;
/*
* We must go ahead and set the text before changing the
* movement method, because setMovementMethod() may call
* setText() again to try to upgrade the buffer type.
*/
mText = text;
// Do not change the movement method for text that support text selection as it
// would prevent an arbitrary cursor displacement.
if (mLinksClickable && !textCanBeSelected()) {
setMovementMethod(LinkMovementMethod.getInstance());
}
}
}
所以我花了一些时间去理解, 为什么我在ListView项中禁用链接, 但有时它会获取一个链接!
您需要将该标志设置为所需的值, 然后调用setText(...)
return true;
移到内部 if 的正向分支中,以便在触摸保持稳定时突出显示 span。 - A-LivetextView.setMovementMethod(null);
实现的,必须在设置了textView的文本之后调用。 - Ridcully