diff --git a/kotlin-extensions/src/main/java/ru/touchin/extensions/CharSequence.kt b/kotlin-extensions/src/main/java/ru/touchin/extensions/CharSequence.kt
new file mode 100644
index 0000000..bd4fe7d
--- /dev/null
+++ b/kotlin-extensions/src/main/java/ru/touchin/extensions/CharSequence.kt
@@ -0,0 +1,3 @@
+package ru.touchin.extensions
+
+fun CharSequence.indexesOf(substring: String) = Regex(substring).find(this)?.let { it.range.first to it.range.last + 1 }
diff --git a/utils/build.gradle b/utils/build.gradle
index 2a77fe4..2a490af 100644
--- a/utils/build.gradle
+++ b/utils/build.gradle
@@ -1,6 +1,7 @@
apply from: "../android-configs/lib-config.gradle"
dependencies {
+ implementation project(':kotlin-extensions')
implementation "androidx.core:core"
implementation "androidx.annotation:annotation"
diff --git a/utils/src/main/java/ru/touchin/roboswag/components/utils/spans/SpanUtils.kt b/utils/src/main/java/ru/touchin/roboswag/components/utils/spans/SpanUtils.kt
index 25b6fec..b69a0cd 100644
--- a/utils/src/main/java/ru/touchin/roboswag/components/utils/spans/SpanUtils.kt
+++ b/utils/src/main/java/ru/touchin/roboswag/components/utils/spans/SpanUtils.kt
@@ -2,9 +2,15 @@ package ru.touchin.roboswag.components.utils.spans
import android.text.SpannableString
import android.text.Spanned
+import android.text.TextPaint
+import android.text.style.ClickableSpan
+import android.text.style.ForegroundColorSpan
import android.text.style.URLSpan
import android.text.util.Linkify
+import android.view.View
+import androidx.annotation.ColorInt
import androidx.core.text.HtmlCompat
+import ru.touchin.extensions.indexesOf
/**
* Convert text with 'href' tags and raw links to spanned text with clickable URLSpan.
@@ -47,3 +53,28 @@ private fun SpannableString.getUrlSpans() = getSpans(0, length, URLSpan::class.j
.map { UrlSpanWithBorders(it, this.getSpanStart(it), this.getSpanEnd(it)) }
private data class UrlSpanWithBorders(val span: URLSpan, val start: Int, val end: Int)
+
+/**
+ * Find substring inside string (for example in TextView) and fill it with ClickableSpan
+ */
+fun CharSequence.toClickableSubstringText(
+ substring: String,
+ clickAction: () -> Unit,
+ @ColorInt color: Int? = null,
+ isUnderlineText: Boolean = false
+) = SpannableString(this)
+ .apply {
+ indexesOf(substring)?.let { (startSpan, endSpan) ->
+ setSpan(object : ClickableSpan() {
+ override fun onClick(widget: View) {
+ clickAction.invoke()
+ }
+
+ override fun updateDrawState(ds: TextPaint) {
+ super.updateDrawState(ds)
+ ds.isUnderlineText = isUnderlineText
+ if (color != null) ds.color = color
+ }
+ }, startSpan, endSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
+ }
+ }
diff --git a/views/src/main/java/ru/touchin/roboswag/views/ActionTextView.kt b/views/src/main/java/ru/touchin/roboswag/views/ActionTextView.kt
new file mode 100644
index 0000000..39d3ffd
--- /dev/null
+++ b/views/src/main/java/ru/touchin/roboswag/views/ActionTextView.kt
@@ -0,0 +1,44 @@
+package ru.touchin.roboswag.views
+
+import android.content.Context
+import android.graphics.Color
+import android.util.AttributeSet
+import androidx.appcompat.widget.AppCompatTextView
+import androidx.core.content.withStyledAttributes
+import ru.touchin.roboswag.components.utils.movementmethods.ClickableMovementMethod
+import ru.touchin.roboswag.components.utils.spans.toClickableSubstringText
+
+class ActionTextView @JvmOverloads constructor(
+ context: Context,
+ attrs: AttributeSet? = null,
+ defStyleAttr: Int = 0
+) : AppCompatTextView(context, attrs, defStyleAttr) {
+
+ private var onClickAction: () -> Unit = { }
+
+ init {
+ isClickable = false
+ isLongClickable = false
+ highlightColor = Color.TRANSPARENT
+
+ movementMethod = ClickableMovementMethod
+
+ context.withStyledAttributes(attrs, R.styleable.ActionTextView, defStyleAttr, 0) {
+ val actionText = getString(R.styleable.ActionTextView_actionText).orEmpty()
+ val actionColor = getColor(R.styleable.ActionTextView_actionColor, currentTextColor)
+ val isUnderlineText = getBoolean(R.styleable.ActionTextView_isUnderlineText, false)
+
+ text = text.toClickableSubstringText(
+ substring = actionText,
+ clickAction = { onClickAction.invoke() },
+ color = actionColor,
+ isUnderlineText = isUnderlineText
+ )
+ }
+ }
+
+ fun setOnActionClickListener(onClickAction: () -> Unit) {
+ this.onClickAction = onClickAction
+ }
+
+}
diff --git a/views/src/main/res/values/attrs.xml b/views/src/main/res/values/attrs.xml
index b8dce82..9b154af 100644
--- a/views/src/main/res/values/attrs.xml
+++ b/views/src/main/res/values/attrs.xml
@@ -50,4 +50,10 @@
+
+
+
+
+
+