I'm stuck on a little issue using Resource
wrapping around my data, I don't know how I can use it in my databinding.
Sealed class:
sealed class Resource<out T: Any> {
data class Success<out T: Any>(val data: T): Resource<T>()
data class Error(val exception: Throwable): Resource<Nothing>()
object Loading: Resource<Nothing>()
}
I've got this val product: LiveData<Resource<NetworkProductDetails>>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="viewModel"
type="my.package.ProductDetailsViewModel" />
</data>
<TextView
android:id="@+id/product_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{viewModel.product.productName}"
android:textAppearance="?attr/textAppearanceBody1"
android:gravity="center"/>
...
</layout>
I've got an issue because viewModel.product
is not a NetworkProductDetails
but Resource<NetworkProductDetails>
and my XML/Databinding doesn't know how to process it.
I've found a way to make work but I was wondering if there was a more elegant way.
First Solution:
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="viewModel"
type="my.package.ProductDetailsViewModel" />
<variable
name="product"
type="my.package.NetworkProductDetails" />
</data>
<TextView
android:id="@+id/product_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{product.productName}"
android:textAppearance="?attr/textAppearanceBody1"
android:gravity="center"/>
...
</layout>
viewModel.product.observe(viewLifecycleOwner, Observer { it ->
when(it) {
is Resource.Success -> {
binding.product = it.data
}
}
}
Second Solution:
In the comment I made.
After looking around, there is 2 solutions I've found, the first is in my original post and the second is the one below:
Creating a function in my sealed class to expose the data if it is Success
and then be able to use it in my xml
Pros:
BindingAdapter
that could hide some of the logicFragment
like in Solution 1Cons:
sealed class Resource<out T: Any> {
data class Success<out T: Any>(val data: T): Resource<T>()
data class Error(val exception: Throwable): Resource<Nothing>()
object Loading: Resource<Nothing>()
fun toData(): T? = if(this is Success) this.data else null
}
<TextView
android:id="@+id/product_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text='@{viewModel.product.toData()?.productName}'
android:textAppearance="?attr/textAppearanceBody1"
android:gravity="center"/>