[关闭]
@natsumi 2016-08-26T02:27:49.000000Z 字数 2305 阅读 1340

TextView中非ClickableSpan的文字点击事件如何传给父级View

天天的微博客户端


遇到的问题:
继承TextView写了StatusTextView,给微博文字中的@和话题、网址设置了ClickableSpan,其他文字点击事件传递不到父级,无法触发父级View的onClick方法。

参考:
http://stackoverflow.com/questions/8558732/listview-textview-with-linkmovementmethod-makes-list-item-unclickable

解决:
添加一个成员,标识clickableSpan的点击

  1. private boolean mLinkHitFlag;

在StatusTextView中创建一个内部类继承LinkMovementMethod,重写onTouchEvent
其实是将父类的onTouchEvent代码粘过来做了些修改,添加了47-49 58-59行的代码。
47-49行处在点击了link的条件中,此时修改mLinkHitFlag为true

  1. /**
  2. * Created by tiantian on 16-8-24.
  3. * 继承LinkMovementMethod
  4. */
  5. public static class CustomLinkMovementMethod extends LinkMovementMethod {
  6. private static CustomLinkMovementMethod sInstance;
  7. public static CustomLinkMovementMethod getInstance() {
  8. if (sInstance == null) {
  9. sInstance = new CustomLinkMovementMethod();
  10. }
  11. return sInstance;
  12. }
  13. @Override
  14. public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
  15. int action = event.getAction();
  16. if (action == MotionEvent.ACTION_UP ||
  17. action == MotionEvent.ACTION_DOWN) {
  18. int x = (int) event.getX();
  19. int y = (int) event.getY();
  20. x -= widget.getTotalPaddingLeft();
  21. y -= widget.getTotalPaddingTop();
  22. x += widget.getScrollX();
  23. y += widget.getScrollY();
  24. Layout layout = widget.getLayout();
  25. int line = layout.getLineForVertical(y);
  26. int off = layout.getOffsetForHorizontal(line, x);
  27. ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
  28. if (link.length != 0) {
  29. if (action == MotionEvent.ACTION_UP) {
  30. link[0].onClick(widget);
  31. } else if (action == MotionEvent.ACTION_DOWN) {
  32. Selection.setSelection(buffer,
  33. buffer.getSpanStart(link[0]),
  34. buffer.getSpanEnd(link[0]));
  35. }
  36. // tiantian add to modify link hit flag
  37. if(widget instanceof StatusTextView){
  38. ((StatusTextView)widget).mLinkHitFlag=true;
  39. }
  40. return true;
  41. } else {
  42. Selection.removeSelection(buffer);
  43. // tiantian add according to
  44. // http://stackoverflow.com/questions/8558732/listview-textview-with-linkmovementmethod-makes-list-item-unclickable
  45. // tiantian doesn't know why =.=
  46. Touch.onTouchEvent(widget, buffer, event);
  47. return false;
  48. }
  49. }
  50. return super.onTouchEvent(widget, buffer, event);
  51. }
  52. }

构造StatusTextView时用自定义的LinkMovementMethod

  1. setMovementMethod(CustomLinkMovementMethod.getInstance());

重写StatusTextView的onTouchEvent方法,给Flag赋初值为false
若点的是link,Flag将被上面的方法修改为true,于是返回值也为true,消费掉这次点击。
若点的不是link,Flag仍为false,于是返回值为false,将事件传递给父级处理

  1. @Override
  2. public boolean onTouchEvent(MotionEvent event) {
  3. mLinkHitFlag=false;
  4. super.onTouchEvent(event);//应该是这里面调用了LinkMovementMethod的onTouchEvent
  5. return mLinkHitFlag;
  6. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注