How to set SwipeRefreshLayout refreshing property using android data binding?

删除回忆录丶 提交于 2019-11-29 01:53:24

问题


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.


回答1:


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.




回答2:


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:

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);
    }
}



回答3:


Just use this app:refreshing="@{booleanValueHere}". Data Binding will automatically detect the reference back to the isRefreshing function.



来源:https://stackoverflow.com/questions/40960599/how-to-set-swiperefreshlayout-refreshing-property-using-android-data-binding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!