上一篇寫過自定義展開收起的textview,不過最近發現有個問題。
那就是在列表頁中,如果點擊了全部,會觸發view的點擊事件,導致展開后接着進入了詳情。
這顯然不是想要的結果。
這里可以通過自定義LinkMovementMethod來解決。
第一步:
首先先屏蔽掉view的點擊事件,全部用邏輯控制。
這樣的話,就只會響應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的時候添加進去就行了。
看運行效果圖,非常絲滑,正常滑動,點擊,展開。