Extensions.kt 3.95 KB
Newer Older
1
package org.dpppt.android.app.common.util
2

3
import android.content.Context
4
import android.content.res.Resources
5
import android.graphics.Typeface
6
7
import android.text.SpannableString
import android.text.Spanned
8
import android.text.TextPaint
9
10
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
11
import android.text.style.ForegroundColorSpan
12
13
import android.text.style.URLSpan
import android.text.util.Linkify
14
import android.view.View
15
import android.widget.TextView
16
import androidx.core.content.ContextCompat
17
18
19
import androidx.core.content.res.ResourcesCompat
import androidx.core.text.util.LinkifyCompat
import org.dpppt.android.app.R
20
import org.dpppt.android.app.common.ui.TypefaceSpanCompat
21
import org.dpppt.android.app.util.getLanguageCodeFromLocale
Michelle Mueller's avatar
Michelle Mueller committed
22
import java.util.Locale
23
24
25
26

fun TextView.setTextWithBoldSpans(source: String, vararg boldParts: String) {
    val boldTypeFace = Typeface.create(ResourcesCompat.getFont(context, R.font.aino_bold), Typeface.BOLD)
    val boldSpan = TypefaceSpanCompat(boldTypeFace)
27
28
29
30
31
32
33
34
    text = getTextWithSpans(source, boldSpan, *boldParts)
}

fun Context.getTextWithBlueSpans(source: String, vararg blueParts: String): SpannableString {
    val blueColor = ContextCompat.getColor(this, R.color.primary)
    val span = ForegroundColorSpan(blueColor)
    return getTextWithSpans(source, span, *blueParts)
}
35

36
private fun getTextWithSpans(source: String, span: Any, vararg spanParts: String): SpannableString {
37
    val spannable = SpannableString(source)
38
39
    for (part in spanParts) {
        spannable.addSpan(part, span)
40
    }
41
    return spannable
42
}
43
44
45
46
47
48
49
50
51

fun SpannableString.addSpan(spannablePart: String, span: Any): SpannableString {
    val start = this.indexOf(spannablePart)
    val end = start + spannablePart.length
    if (start > -1) {
        setSpan(span, start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
    }
    return this
}
52
53
54
55
56

fun TextView.addUrlSpans() {
    LinkifyCompat.addLinks(this, Linkify.ALL)
    val sourceSpannable = SpannableString(text)
    for (spannable in sourceSpannable.getSpans(0, sourceSpannable.length, URLSpan::class.java)) {
57
58
59
60
61
62
63
64
65
        sourceSpannable.setSpan(
            object : URLSpan(spannable.url) {
                override fun updateDrawState(paint: TextPaint) {
                    super.updateDrawState(paint)
                    updateDrawStateWithPaint(paint, context)
                }
            },
            sourceSpannable.getSpanStart(spannable), sourceSpannable.getSpanEnd(spannable), 0
        )
66
67
68
    }
    text = sourceSpannable
}
69
70
71

fun TextView.setTextWithClickableSpan(source: String, clickablePart: String, clickListener: () -> Unit) {
    val spannable = SpannableString(source)
72
73
74
75
76
77
78
    addClickableSpan(spannable, clickablePart, clickListener)
    this.text = spannable
    movementMethod = LinkMovementMethod.getInstance()
}

private fun TextView.addClickableSpan(
    spannable: SpannableString,
79
80
    clickablePart: String,
    clickListener: () -> Unit
81
) {
82
    spannable.addSpan(
83
        clickablePart,
84
85
        object : ClickableSpan() {
            override fun onClick(widget: View) {
86
                clickListener.invoke()
87
            }
88

89
90
91
92
            override fun updateDrawState(paint: TextPaint) {
                super.updateDrawState(paint)
                updateDrawStateWithPaint(paint, context)
            }
93
        }
94
    )
95
}
Michelle Mueller's avatar
Michelle Mueller committed
96
97
98
99
100
101

private fun updateDrawStateWithPaint(paint: TextPaint, context: Context) {
    paint.isUnderlineText = false
    paint.typeface = ResourcesCompat.getFont(context, R.font.aino_bold)
    paint.color = ContextCompat.getColor(context, R.color.accent)
}
Michelle Mueller's avatar
Michelle Mueller committed
102

103
@Suppress("DEPRECATION")
104
fun Context.overrideLanguage(locale: Locale?): Context? {
105
    val language = locale ?: Locale(getLanguageCodeFromLocale())
Michelle Mueller's avatar
Michelle Mueller committed
106
    Locale.setDefault(language)
107
    val configuration = this.resources.configuration
108
    configuration.locale = language
Michelle Mueller's avatar
Michelle Mueller committed
109
110
    return createConfigurationContext(configuration)
}
111
112
113
114
115

@Suppress("DEPRECATION")
fun Resources.updateConfiguration() {
    updateConfiguration(configuration, displayMetrics)
}