How to set SwipeRefreshLayout refreshing property using android data binding?
UPDATED:
As databinding maps from xml attribute name to set{AttributeName}
, you can just use app:refreshing
, as databinding will successfully supply the value to setRefreshing
method of SwipeRefreshLayout
(which luckily for us exists and is public):
<android.support.v4.widget.SwipeRefreshLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:refreshing="@{habitListViewModel.isLoading}">
...
//ListView,RecyclerView or something
</android.support.v4.widget.SwipeRefreshLayout>
That's it! Note, that you can simply use @{true}
or @{false}
instead of @{habitListViewModel.isLoading}
. Hope that helps.
No need to hack. The key is to look for the public methods in SwipeRefreshLayout documentation. In general, Databinding will look for the corresponding name without the set
part. E.g. you'll find there:
- setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener listener)
- setRefreshing(boolean refreshing)
The OnRefreshListener
Since OnRefreshListener is a public interface, with a single method, you can directly use this in your binding, like so:
app:onRefreshListener="@{() -> viewModel.onRefresh()}"
Updating the Status
For this one, you use the other public method, which translates to:
app:refreshing="@{viewModel.isLoading}"
All together, it can look something like this:
<data>
<variable name="viewModel" type="ViewModel" />
</data>
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:refreshing="@{viewModel.isLoading}"
app:onRefreshListener="@{() -> viewModel.onRefresh()}">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
viewmodel - kotlin :
class ViewModel(
private val provider: DataProvider
) : DataProvider.Callback {
/* isLoading - Needs to be public for Databinding! */
val isLoading = ObservableBoolean()
/* onRefresh() - Needs to be public for Databinding! */
fun onRefresh() {
isLoading.set(true)
provider.fetch(this)
}
fun onReady() = isLoading.set(false)
fun onError(oops: Exception) = isLoading.set(false)
}
viewmodel - java:
public class ViewModel implements DataProvider.Callback {
public ObservableBoolean isLoading = new ObservableBoolean();
private DataProvider provider;
MasterViewModel(@NonNull final DataProvider provider) {
this.provider = provider;
}
/* Needs to be public for Databinding */
public void onRefresh() {
isLoading.set(true);
provider.fetch(this);
}
public void onReady(List results){
isLoading.set(false);
}
public void onError(Exception oops){
isLoading.set(false);
Log.e("Stack", oops);
}
}