Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set SwipeRefreshLayout refreshing property using android data binding?

I am using android data binding library. If I want to make a view visible I can write something like this:

<TextView             android:id="@+id/label_status"             android:layout_width="match_parent"             android:layout_height="wrap_content"             android:gravity="center"             android:text="@{habitListViewModel.message}"             app:visibility="@{habitListViewModel.hasError ? View.VISIBLE : View.GONE}" /> 

Is there an option to bind to a refresh property of swipeRefreshLayout in a similar (xml) way?

Currently I am setting it in code by calling setRefreshing(true/false) but would love to make it in xml to be consistent.

like image 503
daneejela Avatar asked Dec 04 '16 16:12

daneejela


People also ask

What is SwipeRefreshLayout?

Android SwipeRefreshLayout is a ViewGroup that can hold only one scrollable child. It can be either a ScrollView, ListView or RecyclerView. The basic need for a SwipeRefreshLayout is to allow the users to refresh the screen manually. This is pretty common in the Facebook Newsfeed screen.

How do I stop swipe refresh layout?

To disable the gesture and progress animation, call setEnabled(false) on the view. This layout should be made the parent of the view that will be refreshed as a result of the gesture and can only support one direct child.

Why we use data binding in Android?

Data Binding allows you to effortlessly communicate across views and data sources. This pattern is important for many Android designs, including model view ViewModel (MVVM), which is currently one of the most common Android architecture patterns.


1 Answers

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);     } } 
like image 169
Entreco Avatar answered Oct 02 '22 13:10

Entreco