From d85fe7a128be6f31c8cae06738c7b8684ee39f4d Mon Sep 17 00:00:00 2001 From: LooKeR Date: Fri, 29 Oct 2021 15:01:12 +0530 Subject: [PATCH] Fix: Links in Description not clickable (Closes #91) --- .../looker/droidify/screen/ProductAdapter.kt | 5 +- .../widget/ClickableMovementMethod.kt | 67 +++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/com/looker/droidify/widget/ClickableMovementMethod.kt diff --git a/src/main/kotlin/com/looker/droidify/screen/ProductAdapter.kt b/src/main/kotlin/com/looker/droidify/screen/ProductAdapter.kt index cfd063f6..29705de6 100644 --- a/src/main/kotlin/com/looker/droidify/screen/ProductAdapter.kt +++ b/src/main/kotlin/com/looker/droidify/screen/ProductAdapter.kt @@ -22,6 +22,7 @@ import android.view.Gravity import android.view.MotionEvent import android.view.View import android.view.ViewGroup +import android.widget.TextView import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.widget.LinearLayoutCompat import androidx.core.content.res.ResourcesCompat @@ -52,6 +53,7 @@ import com.looker.droidify.utility.Utils import com.looker.droidify.utility.extension.android.* import com.looker.droidify.utility.extension.resources.* import com.looker.droidify.utility.extension.text.* +import com.looker.droidify.widget.ClickableMovementMethod import com.looker.droidify.widget.StableRecyclerAdapter import java.lang.ref.WeakReference import java.util.* @@ -406,7 +408,7 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int) private class TextViewHolder(context: Context) : RecyclerView.ViewHolder(MaterialTextView(context)) { - val text: MaterialTextView + val text: TextView get() = itemView as MaterialTextView init { @@ -414,6 +416,7 @@ class ProductAdapter(private val callbacks: Callbacks, private val columns: Int) itemView.setTextSizeScaled(15) itemView.setTextColor(itemView.context.getColorFromAttr(android.R.attr.textColor)) itemView.resources.sizeScaled(16).let { itemView.setPadding(it, it, it, it) } + itemView.movementMethod = ClickableMovementMethod itemView.layoutParams = RecyclerView.LayoutParams( RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT diff --git a/src/main/kotlin/com/looker/droidify/widget/ClickableMovementMethod.kt b/src/main/kotlin/com/looker/droidify/widget/ClickableMovementMethod.kt new file mode 100644 index 00000000..8d48a5d5 --- /dev/null +++ b/src/main/kotlin/com/looker/droidify/widget/ClickableMovementMethod.kt @@ -0,0 +1,67 @@ +package com.looker.droidify.widget + +import android.text.Selection +import android.text.Spannable +import android.text.method.MovementMethod +import android.text.style.ClickableSpan +import android.view.KeyEvent +import android.view.MotionEvent +import android.widget.TextView + +object ClickableMovementMethod : MovementMethod { + override fun initialize(widget: TextView, text: Spannable) { + Selection.removeSelection(text) + } + + override fun onTouchEvent(widget: TextView, text: Spannable, event: MotionEvent): Boolean { + val action = event.action + val down = action == MotionEvent.ACTION_DOWN + val up = action == MotionEvent.ACTION_UP + return (down || up) && run { + val x = event.x.toInt() - widget.totalPaddingLeft + widget.scrollX + val y = event.y.toInt() - widget.totalPaddingTop + widget.scrollY + val layout = widget.layout + val line = layout.getLineForVertical(y) + val offset = layout.getOffsetForHorizontal(line, x.toFloat()) + val span = text.getSpans(offset, offset, ClickableSpan::class.java)?.firstOrNull() + if (span != null) { + if (down) { + Selection.setSelection(text, text.getSpanStart(span), text.getSpanEnd(span)) + } else { + span.onClick(widget) + } + true + } else { + Selection.removeSelection(text) + false + } + } + } + + override fun onKeyDown( + widget: TextView, + text: Spannable, + keyCode: Int, + event: KeyEvent, + ): Boolean = false + + override fun onKeyUp( + widget: TextView, + text: Spannable, + keyCode: Int, + event: KeyEvent, + ): Boolean = false + + override fun onKeyOther(view: TextView, text: Spannable, event: KeyEvent): Boolean = false + override fun onTakeFocus(widget: TextView, text: Spannable, direction: Int) = Unit + override fun onTrackballEvent(widget: TextView, text: Spannable, event: MotionEvent): Boolean = + false + + override fun onGenericMotionEvent( + widget: TextView, + text: Spannable, + event: MotionEvent, + ): Boolean = false + + override fun canSelectArbitrarily(): Boolean = false +}