I'm kinda stack with this scenario actually, Since I need to span some characters in my string, but still gives me a plain text. Do you guys have any suggestion here how to use SpannableString
not directly using in TextView
but instead assigning this to the String
object and will be use later on the TextView
? It is obvious it will work inside the activity and fragment. but I'm working on the outside of the context since I'm using a shared component.
example:
I have here a ui factory.
fun DataDto.spanSomeText(resource: Resources): SpannableStringBuilder {
val stringBuilder = SpannableStringBuilder()
val spannedText = SpannableString(resource.getString(R.string.text_label)).apply {
setSpan(**implementation**)
}
return stringBuilder
.append(resource.getString(spannedText))
.append(resource.getString(dataDtoObject, formatString))
}
then I have a data class will handle this objects from this dto.
// this is from another package that is shared component
DataClassToUi(
textfield: @RawValue Any?
) {
fun getString(context): CharSequence? = when(textfield) {
is OtherStringHander -> textfield.cleanString(context)
is SpannableStringBuilder,
is SpannableString -> textfield as CharSequence
else -> throw IllegalArgumentException("data type is not string")
}
}
fun DataDto.toDetails(resource: Resources) = DataClassToUi(
textfield = data.spanSomeText(resource)
)
and on the xml
<layout>
<data>
<variable
name="data"
type="path.DataClassToUi" />
</data>
<TextView>
android:text="@{data.getString(context)}"
</TextView>
</layout>
A String
is just plain text, it's just a bunch of characters, so when you call toString
you're basically stripping out all your extra data about the spans etc
String
implements CharSequence
, which is a more general text representation that can hold all that extra data - and a SpannableStringBuilder
itself is a CharSequence
. So you can use it directly in a TextView
with its setText(charSequence)
method, or you can store it in a CharSequence
variable to be passed around your app.
So it'll probably work if you just make fun DataDto.spanSomeText
return a CharSequence
instead of a String
, and pass back stringBuilder
itself instead of calling toString
on it. DataClassToUi.textField
will have to be a CharSequence
too though - since String
s are CharSequence
s anything that was already using String
s should be ok, but you might have to add some toString
calls, and you won't be able to serialise the CharSequence
as easily (since it's an interface, it could be any kind of object, can't just throw it in a SharedPreferences
or whatever like you can with a String
)