listview中在item里的textview设置了setMovementMethod(LinkMovementMethod.getInstance());后,
list的clickitem失效问题解决办法
参考:http://stackoverflow.com/questions/8558732/listview-textview-with-linkmovementmethod-makes-list-item-unclickable
方法一、二:
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) {
// 一、 listview setOnItemLongClickListener BUG
// linkHit = false;
// boolean res = super.onTouchEvent(event);
//
// if (dontConsumeNonUrlClicks)
// return linkHit;
// return res;
// 二、有误触textview内链接BUG
if (getMovementMethod() == null) {
boolean result = super.onTouchEvent(event);
return result;
}
MovementMethod m = getMovementMethod();
setMovementMethod(null);
boolean mt = m.onTouchEvent(this, (Spannable) getText(), event);
if (mt && event.getAction() == MotionEvent.ACTION_DOWN) {
event.setAction(MotionEvent.ACTION_UP);
mt = m.onTouchEvent(this, (Spannable) getText(), event);
event.setAction(MotionEvent.ACTION_DOWN);
}
boolean st = super.onTouchEvent(event);
setMovementMethod(m);
setFocusable(false);
return mt || st;
}
@Override
public boolean hasFocusable() {
return false;
}
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);
}
}
}
使用:
<com.TextViewFixTouchConsume
android:id="@+id/bc_con"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lineSpacingExtra="5dp"
android:textColor="@color/tvcolor_w"
android:textSize="16sp" />
h.tvContent.setMovementMethod(LocalLinkMovementMethod.getInstance());
方法三:
BUG:textview的setOnClickListener 失效
public class TextViewFixTouchConsume extends TextView {
boolean dontConsumeNonUrlClicks = true;
boolean linkHit;
public TextViewFixTouchConsume(Context context) {
super(context);
init();
}
public TextViewFixTouchConsume(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TextViewFixTouchConsume(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
boolean ret = false;
CharSequence text = ((TextView) v).getText();
Spannable stext = Spannable.Factory.getInstance().newSpannable(text);
TextView widget = (TextView) v;
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 = stext.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
if (action == MotionEvent.ACTION_UP) {
link[0].onClick(widget);
}
ret = true;
}
}
return ret;
}
});
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (getMovementMethod() == null) {
boolean result = super.onTouchEvent(event);
return result;
}
MovementMethod m = getMovementMethod();
setMovementMethod(null);
boolean mt = m.onTouchEvent(this, (Spannable) getText(), event);
if (mt && event.getAction() == MotionEvent.ACTION_DOWN) {
event.setAction(MotionEvent.ACTION_UP);
mt = m.onTouchEvent(this, (Spannable) getText(), event);
event.setAction(MotionEvent.ACTION_DOWN);
}
boolean st = super.onTouchEvent(event);
setMovementMethod(m);
setFocusable(false);
return mt || st;
}
@Override
public boolean hasFocusable() {
return false;
}
}
使用:
<com.TextViewFixTouchConsume
android:id="@+id/bc_con"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lineSpacingExtra="5dp"
android:textColor="@color/tvcolor_w"
android:textSize="16sp" />
h.tvContent.setMovementMethod(LinkMovementMethod.getInstance());