From ee4c4aaa5ab44168cff449b3b486755114adffd7 Mon Sep 17 00:00:00 2001 From: Kirill Nayduik Date: Tue, 25 Jan 2022 18:38:05 +0300 Subject: [PATCH 1/2] Add StyleableSubTextView to support styling substrings of text --- .../views/text_view/StyleableSubTextView.kt | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 views/src/main/java/ru/touchin/roboswag/views/text_view/StyleableSubTextView.kt diff --git a/views/src/main/java/ru/touchin/roboswag/views/text_view/StyleableSubTextView.kt b/views/src/main/java/ru/touchin/roboswag/views/text_view/StyleableSubTextView.kt new file mode 100644 index 0000000..2851042 --- /dev/null +++ b/views/src/main/java/ru/touchin/roboswag/views/text_view/StyleableSubTextView.kt @@ -0,0 +1,35 @@ +package ru.touchin.roboswag.views.text_view + +import android.content.Context +import android.util.AttributeSet +import androidx.core.content.withStyledAttributes +import ru.touchin.extensions.getResourceIdOrNull +import ru.touchin.roboswag.components.utils.spans.toStyleableSubstringText +import ru.touchin.roboswag.views.R + +/** + * A [android.widget.TextView] which support styling substrings of text + */ +class StyleableSubTextView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +): EllipsizeSpannableTextView(context, attrs, defStyleAttr) { + + init { + context.withStyledAttributes(attrs, R.styleable.StyleableSubTextView, defStyleAttr, 0) { + val substring = getString(R.styleable.StyleableSubTextView_subtext) + val subtextStyle = getResourceIdOrNull(R.styleable.StyleableSubTextView_subtextStyle) + + if (subtextStyle != null && substring != null) { + text = text.toStyleableSubstringText( + substring = substring, + styleId = subtextStyle, + context = context + ) + } + + } + } + +} From 3d01b780be153a9e87f0f517527074899cbf3a02 Mon Sep 17 00:00:00 2001 From: Kirill Nayduik Date: Wed, 26 Jan 2022 16:58:24 +0300 Subject: [PATCH 2/2] Action TextViews bugfix --- .../components/utils/spans/SpanUtils.kt | 5 ++-- .../views/text_view/MultipleActionTextView.kt | 30 +++---------------- 2 files changed, 7 insertions(+), 28 deletions(-) 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 98655e5..095443e 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 @@ -76,7 +76,6 @@ fun CharSequence.toClickableSubstringText( } override fun updateDrawState(ds: TextPaint) { - super.updateDrawState(ds) ds.isUnderlineText = isUnderlineText } } @@ -92,7 +91,9 @@ fun CharSequence.toStyleableSubstringText( private fun CharSequence.toSubstringSpannable( substring: String, span: Any? -) = SpannableString(this) +) = toSpannable() .apply { indexesOf(substring)?.let { (startSpan, endSpan) -> setSpan(span, startSpan, endSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) } } + +private fun CharSequence.toSpannable() = if (this is SpannableString) this else SpannableString(this) diff --git a/views/src/main/java/ru/touchin/roboswag/views/text_view/MultipleActionTextView.kt b/views/src/main/java/ru/touchin/roboswag/views/text_view/MultipleActionTextView.kt index e41fd3f..130fe56 100644 --- a/views/src/main/java/ru/touchin/roboswag/views/text_view/MultipleActionTextView.kt +++ b/views/src/main/java/ru/touchin/roboswag/views/text_view/MultipleActionTextView.kt @@ -2,18 +2,13 @@ package ru.touchin.roboswag.views.text_view import android.content.Context import android.graphics.Color -import android.text.Spanned -import android.text.TextPaint -import android.text.style.ClickableSpan -import android.text.style.TextAppearanceSpan import android.util.AttributeSet -import android.view.View -import androidx.annotation.ColorInt +import androidx.annotation.StyleRes import androidx.core.content.withStyledAttributes import androidx.core.text.toSpannable import ru.touchin.extensions.getResourceIdOrNull -import ru.touchin.extensions.indexesOf import ru.touchin.roboswag.components.utils.movementmethods.ClickableMovementMethod +import ru.touchin.roboswag.components.utils.spans.toClickableSubstringText import ru.touchin.roboswag.views.R /** @@ -28,7 +23,7 @@ class MultipleActionTextView @JvmOverloads constructor( private val onClickActions = mutableListOf() - @ColorInt + @StyleRes private var textStyle: Int? = null private var isUnderlineText = false @@ -52,24 +47,7 @@ class MultipleActionTextView @JvmOverloads constructor( private fun applyActionSpans() { text = text.toSpannable().apply { - onClickActions.forEach { (substring, action) -> - - indexesOf(substring)?.let { (startSpan, endSpan) -> - - setSpan(object : ClickableSpan() { - override fun onClick(widget: View) { - action.invoke() - } - - override fun updateDrawState(ds: TextPaint) { - super.updateDrawState(ds) - ds.isUnderlineText = isUnderlineText - } - }, startSpan, endSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) - - textStyle?.let { setSpan(TextAppearanceSpan(context, it), startSpan, endSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) } - } - } + onClickActions.forEach { (substring, action) -> toClickableSubstringText(substring, action, isUnderlineText, textStyle, context) } } }