评论

收藏

[Android] LinkMovementMethod「解决点击ClickableSpan触发view点击事件」

移动开发 移动开发 发布于:2021-08-18 20:19 | 阅读数:512 | 评论:0

上一篇写过自定义展开收起的textview,不过最近发现有个问题。
那就是在列表页中,如果点击了全部,会触发view的点击事件,导致展开后接着进入了详情。
DSC0000.gif

这显然不是想要的结果。
这里可以通过自定义LinkMovementMethod来解决。
第一步:
首先先屏蔽掉view的点击事件,全部用逻辑控制。
DSC0001.png

这样的话,就只会响应ClickableSpan事件了。
第二步:
接下来就需要通过LinkMovementMethod来控制了。
点进去看LinkMovementMethod的代码,可以看到是在onTouchEvent中处理的。
参数中的textview就是我们的自定义展开收起view。
@Override
  public boolean onTouchEvent(TextView widget, Spannable buffer,
                MotionEvent event) {
    if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
      ...
      ClickableSpan[] links = buffer.getSpans(off, off, ClickableSpan.class);
      if (links.length != 0) {
        ClickableSpan link = links[0];
        if (action == MotionEvent.ACTION_UP) {
          if (link instanceof TextLinkSpan) {
            ((TextLinkSpan) link).onClick(
                widget, TextLinkSpan.INVOCATION_METHOD_TOUCH);
          } else {
            link.onClick(widget);
          }
        } else if (action == MotionEvent.ACTION_DOWN) {
          Selection.setSelection(buffer,
              buffer.getSpanStart(link),
              buffer.getSpanEnd(link));
        }
        return true;
      } else {
        Selection.removeSelection(buffer);
      }
    }
    return super.onTouchEvent(widget, buffer, event);
  }
现在就是要改变这里的逻辑,我这里直接把这个类复制出来,然后其它不变,直接处理这块逻辑。
if (links.length != 0) {
        if (action == MotionEvent.ACTION_UP) {
          links[0].onClick(widget);
        } else if (action == MotionEvent.ACTION_DOWN) {
          Selection.setSelection(buffer,
              buffer.getSpanStart(links[0]),
              buffer.getSpanEnd(links[0]));
        }
        //Log.e("onTouchEvent","点击了tip");
        return true;
      } else {
        if (action == MotionEvent.ACTION_UP) {//防止滑动触发
          //Log.e("onTouchEvent", "点击了其它");
          Selection.removeSelection(buffer);
          widget.performClick();
          return super.onTouchEvent(widget, buffer, event);
        }
      }
    }
    //Log.e("onTouchEvent","onTouchEvent");
    return super.onTouchEvent(widget, buffer, event);
上面的 widget.performClick() 就是触发了view的点击事件,这里就可以随意控制点击事件了。
在设置span的时候添加进去就行了。
DSC0002.png

看运行效果图,非常丝滑,正常滑动,点击,展开。
DSC0003.gif



   
   
   


关注下面的标签,发现更多相似文章