Created
November 7, 2018 02:23
-
-
Save dyguests/ce7135522e000dba30ac8b33ed8e4aff to your computer and use it in GitHub Desktop.
使 TextView 的 ClickSpan 可以响应,但是不影响 原TextView其它区域的点击处理,防止父控件无响应
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.text.Selection | |
import android.text.Spannable | |
import android.text.Spanned | |
import android.text.method.BaseMovementMethod | |
import android.text.style.ClickableSpan | |
import android.view.MotionEvent | |
import android.view.View | |
import android.widget.TextView | |
/** | |
* see [https://blog.csdn.net/zhaizu/article/details/51038113] | |
* | |
* 使用方法: | |
* | |
* // more code | |
* TextView content = new TextView(getContext()); | |
* // more code | |
* content.setMovementMethod(ClickableMovementMethod.getInstance()); | |
* content.setOnTouchListener(ClickableMovementMethod.getInstance()); | |
* content.setFocusable(false); | |
* content.setClickable(false); | |
* content.setLongClickable(false); | |
* --------------------- | |
* 作者:zhaizu | |
* 来源:CSDN | |
* 原文:https://blog.csdn.net/zhaizu/article/details/51038113 | |
* 版权声明:本文为博主原创文章,转载请附上博文链接! | |
*/ | |
internal class ClickableMovementMethod : BaseMovementMethod(), View.OnTouchListener { | |
override fun onTouchEvent(widget: TextView, buffer: Spannable, event: MotionEvent): Boolean { | |
val action = event.actionMasked | |
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { | |
var x = event.x.toInt() | |
var y = event.y.toInt() | |
x -= widget.totalPaddingLeft | |
y -= widget.totalPaddingTop | |
x += widget.scrollX | |
y += widget.scrollY | |
val layout = widget.layout | |
val line = layout.getLineForVertical(y) | |
val off = layout.getOffsetForHorizontal(line, x.toFloat()) | |
val link = buffer.getSpans(off, off, ClickableSpan::class.java) | |
if (link.size > 0) { | |
if (action == MotionEvent.ACTION_UP) { | |
link[0].onClick(widget) | |
} else { | |
Selection.setSelection( | |
buffer, buffer.getSpanStart(link[0]), | |
buffer.getSpanEnd(link[0]) | |
) | |
} | |
return true | |
} else { | |
Selection.removeSelection(buffer) | |
} | |
} | |
return false | |
} | |
override fun onTouch(v: View, event: MotionEvent): Boolean { | |
val widget = v as TextView | |
val text = widget.text | |
if (text is Spanned) { | |
val action = event.action | |
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { | |
var x = event.x.toInt() | |
var y = event.y.toInt() | |
x -= widget.totalPaddingLeft | |
y -= widget.totalPaddingTop | |
x += widget.scrollX | |
y += widget.scrollY | |
val layout = widget.layout | |
val line = layout.getLineForVertical(y) | |
val off = layout.getOffsetForHorizontal(line, x.toFloat()) | |
val link = text.getSpans( | |
off, off, | |
ClickableSpan::class.java | |
) | |
if (link.size != 0) { | |
if (action == MotionEvent.ACTION_UP) { | |
link[0].onClick(widget) | |
} else if (action == MotionEvent.ACTION_DOWN) { | |
// Selection only works on Spannable text. In our case setSelection doesn't work on spanned text | |
// Selection.setSelection((Spannable) buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0])); | |
} | |
return true | |
} | |
} | |
} | |
return false | |
} | |
override fun initialize(widget: TextView, text: Spannable) { | |
Selection.removeSelection(text) | |
} | |
companion object { | |
private var sInstance: ClickableMovementMethod? = null | |
val instance: ClickableMovementMethod | |
get() { | |
if (sInstance == null) { | |
sInstance = ClickableMovementMethod() | |
} | |
return sInstance!! | |
} | |
/** | |
* 使 TextView 的 ClickSpan 可以响应,但是不影响 原TextView其它区域的点击处理,防止父控件无响应 | |
*/ | |
fun setupTextView(textView: TextView) { | |
textView.apply { | |
movementMethod = ClickableMovementMethod.instance | |
setOnTouchListener(ClickableMovementMethod.instance) | |
isFocusable = false | |
isClickable = false | |
isLongClickable = false | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment