Last active
September 28, 2020 07:27
-
-
Save dostalleos/ea2d218cffa6be3476246e17564a88b0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sealed class TextRes { | |
abstract val resId: Int | |
data class Regular( | |
override val resId: Int | |
) : TextRes() { | |
override fun equals(other: Any?): Boolean { | |
if (this === other) return true | |
if (other !is Regular) return false | |
if (resId != other.resId) return false | |
return true | |
} | |
override fun hashCode(): Int { | |
return resId | |
} | |
} | |
class Quantity( | |
override val resId: Int, | |
val quantity: Int, | |
vararg values: Any? | |
) : TextRes() { | |
val args = values | |
override fun equals(other: Any?): Boolean { | |
if (this === other) return true | |
if (other !is Quantity) return false | |
if (resId != other.resId) return false | |
if (quantity != other.quantity) return false | |
if (!args.contentEquals(other.args)) return false | |
return true | |
} | |
override fun hashCode(): Int { | |
var result = resId | |
result = 31 * result + quantity | |
result = 31 * result + args.contentHashCode() | |
return result | |
} | |
} | |
class Formatted( | |
override val resId: Int, | |
vararg values: Any? | |
) : TextRes() { | |
val args = values | |
override fun equals(other: Any?): Boolean { | |
if (this === other) return true | |
if (other !is Formatted) return false | |
if (resId != other.resId) return false | |
if (!args.contentEquals(other.args)) return false | |
return true | |
} | |
override fun hashCode(): Int { | |
var result = resId | |
result = 31 * result + args.contentHashCode() | |
return result | |
} | |
} | |
} | |
@SuppressWarnings("SpreadOperator", "NestedBlockDepth") | |
@BindingAdapter("textRes") | |
fun TextView.setTextRes(stringRes: TextRes?) { | |
val newText = when (stringRes) { | |
is TextRes.Regular -> context.getString(stringRes.resId) | |
is TextRes.Formatted -> context.getString(stringRes.resId, *stringRes.args) | |
is TextRes.Quantity -> context.resources.getQuantityString(stringRes.resId, stringRes.quantity, *stringRes.args) | |
null -> "" | |
} | |
val oldText = text | |
// save layout passes, should apply to all other | |
if (haveContentsChanged(newText, oldText)) { | |
text = newText | |
} | |
} | |
@BindingAdapter("textRes") | |
fun TextView.setTextRes(stringRes: Int?) { | |
val newText = if (stringRes != null && stringRes != 0) context.getString(stringRes) else "" | |
val oldText = text | |
// save layout passes, should apply to all other | |
if (haveContentsChanged(newText, oldText)) { | |
text = newText | |
} | |
} | |
@BindingAdapter(value = ["spannableText", "links"], requireAll = true) | |
fun TextView.setSpannableLinks(spannable: String, links: HashMap<Int, () -> Unit>) { | |
val span = SpannableStringBuilder(spannable) | |
for ((link, callback) in links) { | |
val customSpan = CustomClickableSpan(context, callback, currentTextColor) | |
val linkSpan = resources.getString(link) | |
val startLink = spannable.indexOf(linkSpan) | |
val endLink = startLink + linkSpan.length | |
if (startLink >= 0) span.setSpan(customSpan, startLink, endLink, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) | |
} | |
text = span | |
} | |
@SuppressWarnings("ReturnCount") | |
private fun haveContentsChanged(str1: CharSequence?, str2: CharSequence?): Boolean { | |
if (str1 == null != (str2 == null)) { | |
return true | |
} else if (str1 == null) { | |
return false | |
} | |
val length = str1.length | |
if (length != str2!!.length) { | |
return true | |
} | |
for (i in 0 until length) { | |
if (str1[i] != str2[i]) { | |
return true | |
} | |
} | |
return false | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment