在这种情况下,存在三个阻碍因素。根本原因是当你打电话时setMovementMethod
or setKeyListener
, TextView
“修复”它的设置:
setFocusable(true);
setClickable(true);
setLongClickable(true);
第一个问题是,当视图可点击时 - 它总是消耗ACTION_UP
事件(它返回 trueonTouchEvent(MotionEvent event)
).
要解决此问题,您应该仅在用户实际单击 URL 时才在该方法中返回 true。
But the LinkMovementMethod
没有告诉我们用户是否确实单击了链接。它返回“true”onTouch
如果用户单击链接,而且在许多其他情况下也是如此。
所以,实际上我在这里做了一个技巧:
public class TextViewFixTouchConsume extends TextView {
boolean dontConsumeNonUrlClicks = true;
boolean linkHit;
public TextViewFixTouchConsume(Context context) {
super(context);
}
public TextViewFixTouchConsume(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TextViewFixTouchConsume(
Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
linkHit = false;
boolean res = super.onTouchEvent(event);
if (dontConsumeNonUrlClicks)
return linkHit;
return res;
}
public void setTextViewHTML(String html)
{
CharSequence sequence = Html.fromHtml(html);
SpannableStringBuilder strBuilder =
new SpannableStringBuilder(sequence);
setText(strBuilder);
}
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 TextViewFixTouchConsume){
((TextViewFixTouchConsume) widget).linkHit = true;
}
return true;
} else {
Selection.removeSelection(buffer);
Touch.onTouchEvent(widget, buffer, event);
return false;
}
}
return Touch.onTouchEvent(widget, buffer, event);
}
}
}
你应该打电话到某个地方
textView.setMovementMethod(
TextViewFixTouchConsume.LocalLinkMovementMethod.getInstance()
);
为textView 设置此MovementMethod。
这个运动方法在TextViewFixTouchConsume
如果用户确实点击了链接。
(只有在ACTION_UP
and ACTION_DOWN
事件)和TextViewFixTouchConsume.onTouchEvent
仅当用户实际点击链接时才返回 true。
但这还不是全部!!!!
第三个问题是ListView
(AbsListView
)称之为performClick
方法(调用onItemClick
事件处理程序)仅当ListView
的项目视图没有焦点。
所以,你需要重写
@Override
public boolean hasFocusable() {
return false;
}
在您添加到的视图中ListView
。
(在我的例子中,这是一个包含 textView 的布局)
或者你可以使用setOnClickLIstener
为了那个观点。
这个技巧不是很好,但是很有效。