Kotlin 版本对@user5699130 的回答:
布局
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="all"/>
拦截链接移动方法
import android.text.Spannable
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.view.GestureDetector
import android.view.MotionEvent
import android.widget.TextView
/**
* Usage:
* fooTextView.movementMethod = InterceptedLinkMovementMethod(this)
* Where 'this' implements [TextViewLinkClickListener]
*/
class InterceptedLinkMovementMethod(
private val listener: TextViewLinkClickListener,
) : LinkMovementMethod() {
private lateinit var textView: TextView
private lateinit var spannable: Spannable
private val gestureDetector: GestureDetector by lazy {
GestureDetector(textView.context, SimpleTapListener())
}
override fun onTouchEvent(widget: TextView, buffer: Spannable, event: MotionEvent): Boolean {
textView = widget
spannable = buffer
gestureDetector.onTouchEvent(event)
return false
}
inner class SimpleTapListener : GestureDetector.SimpleOnGestureListener() {
override fun onDown(event: MotionEvent): Boolean = true
override fun onSingleTapConfirmed(event: MotionEvent): Boolean {
val linkText = getLinkText(textView, spannable, event)
val linkType = LinkTypes.getLinkTypeFromText(linkText)
if (linkType != LinkTypes.NONE) {
listener.onLinkClicked(linkText, linkType)
}
return false
}
override fun onLongPress(e: MotionEvent) {
val linkText = getLinkText(textView, spannable, e)
val linkType = LinkTypes.getLinkTypeFromText(linkText)
if (linkType != LinkTypes.NONE) {
listener.onLinkLongClicked(linkText, linkType)
}
}
private fun getLinkText(widget: TextView, buffer: Spannable, event: MotionEvent): String {
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.isEmpty()) return ""
return buffer.subSequence(buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0]))
.toString()
}
}
}
链接类型
import android.util.Patterns
enum class LinkTypes {
PHONE,
WEB_URL,
EMAIL_ADDRESS,
NONE;
companion object {
fun getLinkTypeFromText(text: String): LinkTypes =
when {
Patterns.PHONE.matcher(text).matches() -> PHONE
Patterns.WEB_URL.matcher(text).matches() -> WEB_URL
Patterns.EMAIL_ADDRESS.matcher(text).matches() -> EMAIL_ADDRESS
else -> NONE
}
}
}
TextViewLinkClickListener
interface TextViewLinkClickListener {
fun onLinkClicked(linkText: String, linkTypes: LinkTypes)
fun onLinkLongClicked(linkText: String, linkTypes: LinkTypes)
}