Reputation: 630
context: data binding with a ViewModel, which gets data from a remote source in the form of JSON. I want to display a textual value from that JSON in a TextView, but if the data is absent in the JSON, I want to fall back to a string defined in strings.xml.
android:text="@{viewModel.theText}"
How I currently solved it is with a custom binding adapter that accepts an Any
, and checks if the value is an Int or String:
app:anyText="@{viewModel.theText}"
. The viewModel has something like val theText = json.nullableString ?: R.string.placeholder
.
I'm guessing that this is a problem more people deal with, and I was hoping if someone knows a more elegant solution.
Upvotes: 0
Views: 1398
Reputation: 2550
You do not need an adapter to handle this use Null coalescing operator operator ??
in xml.
Try below code:
android:text="@{viewModel.theText?? @string/your_default_text}"
Use case :
The null coalescing operator (??) chooses the left operand if it isn't null
or the right if the former is null
.
P.S: lean more about DB and expressions here-> https://developer.android.com/topic/libraries/data-binding/expressions
Upvotes: 1
Reputation: 406
You could provide Application context to your ViewModel or Resources and then do something like this:
val theText = json.nullableString ?: resources.getString(R.string.placeholder)
The other option would be keep using binding adapter like you do but I would wrap text input in another object like this:
data class TextWrapper(
val text: String?,
@StringRes val default: Int
)
@BindingAdapter("anyText")
fun TextView.setAnyText(textWrapper: TextWrapper) {
text = textWrapper.text ?: context.getString(textWrapper.default)
}
val theText = TextWrapper(text = json.nullableString, default = R.string.placeholder)
Upvotes: 1