Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/212.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用android数据绑定设置SwipeRefreshLayout刷新属性?_Android_Data Binding_Swiperefreshlayout_Android Layout - Fatal编程技术网

如何使用android数据绑定设置SwipeRefreshLayout刷新属性?

如何使用android数据绑定设置SwipeRefreshLayout刷新属性?,android,data-binding,swiperefreshlayout,android-layout,Android,Data Binding,Swiperefreshlayout,Android Layout,我正在使用android数据绑定库。 如果我想让视图可见,我可以这样写: <TextView android:id="@+id/label_status" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:tex

我正在使用android数据绑定库。 如果我想让视图可见,我可以这样写:

<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}" />
<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>

是否有一个选项可以以类似的(xml)方式绑定到swipeRefreshLayout的刷新属性

目前,我正在通过调用setRefreshing(true/false)在代码中对其进行设置,但希望在xml中使其保持一致

更新: 由于数据绑定从xml属性名称映射到
set{AttributeName}
,您只需使用
app:refreshing
,因为数据绑定将成功地将值提供给
SwipeRefreshLayout
setRefreshing
方法(我们很幸运,它是公共的):


...
//ListView,RecyclerView之类的

就这样!注意,您可以简单地使用
@{true}
@{false}
而不是
@{habitListViewModel.isLoading}
。希望有帮助。

只需使用这个
应用程序:刷新=“@{booleanValueHere}”
。数据绑定将自动检测回isRefreshing函数的引用。

无需破解。关键是在中寻找公共方法。通常,数据绑定将查找没有
集合的相应名称。例如,你会发现:

    public class DiscoverMoviesViewModel extends ViewModel {

        public MutableLiveData<Boolean> isLoading = new MutableLiveData<>(true);
        .
        .
        .
        public void refresh(){
    
            isLoading.setValue(true);
            //do your task
        
        }
 }
OnRefreshListener

由于OnRefreshListener是一个公共接口,只有一个方法,您可以在绑定中直接使用它,如下所示:

app:onRefreshListener="@{() -> viewModel.onRefresh()}"
更新状态

对于这一个,您使用另一个公共方法,它转换为:

app:refreshing="@{viewModel.isLoading}"
总之,它可以看起来像这样:

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

确保已将
binding.viewModel
设置为片段/活动中的当前实例

这是我的案例中缺失的片段

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    FragmentDiscoverMoviesBinding binding =
            DataBindingUtil.inflate(inflater, R.layout.fragment_discover_movies, container, false);
    viewModel = obtainViewModel(getActivity());       //get the viewmodel from the viewmodelFactory
    binding.setViewModel(viewModel);

    View rootView = binding.getRoot();
    return rootView;
}
fragment_discover_movies.xml

<data>
    <variable
        name="viewModel"
        type="com.ajdi.yassin.popularmovies.ui.movieslist.discover.DiscoverMoviesViewModel" />
</data>

<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:onRefreshListener="@{()-> viewModel.refresh()}"
    app:refreshing="@{viewModel.isLoading}">
    ...
    //ListView,RecyclerView or something
</android.support.v4.widget.SwipeRefreshLayout>

...
//ListView,RecyclerView之类的
然后在viewmodel中定义刷新函数

    public class DiscoverMoviesViewModel extends ViewModel {

        public MutableLiveData<Boolean> isLoading = new MutableLiveData<>(true);
        .
        .
        .
        public void refresh(){
    
            isLoading.setValue(true);
            //do your task
        
        }
 }
公共类DiscoverMoviesViewModel扩展了ViewModel{
public MutableLiveData isLoading=新的MutableLiveData(true);
.
.
.
公共无效刷新(){
isLoading.setValue(真);
//完成你的任务
}
}

很抱歉响应太晚……但是,当将app:refreshing值设置为true/false时,swipeRefreshLayout如何知道预期的行为?我不应该把它和一些行为联系起来吗?它将如何将app:refreshing属性与其设置刷新行为的内部刷新字段相连接?这就是为什么我称它为“一个小黑客”——这里的主要问题是Android数据绑定只是在绑定到对象属性时寻找对象的
set{Name}
方法。这就是为什么我们调用自定义属性
刷新
。因此,当您绑定到它的某个值时,它将只查找
setRefreshing
方法的
SwipeRefreshLayout
对象,我们的对象正好包含该方法,因此行为将与您以编程方式调用
setRefreshing(true/false)
的行为相同:)现在我明白了!斯马特:)谢谢你的解释!不客气:)这是一个不寻常的情况,因此解释是:)不需要attrs.xml,只需使用
android:refreshing=“@{habitListViewModel.isLoading}”
这是您应该如何使用数据绑定库,并且应该是公认的答案。在我的情况下,应用程序:onRefreshListener不调用方法onRefresh。它只让微调器旋转,但不调用onRefresh。它对你有用吗?app:onRefreshListener仅设置侦听器。要真正开始刷新,需要触发事件。在这个示例中,我通过调用
isLoading.set(true)
@enterco来完成,当我向下滑动以刷新时,永远不会调用onRefresh()。因此,使用您的示例,我的问题是,
provider.fetch(this)
从未被调用。@user1795832您必须将“viewModel”设置为片段(或活动)中它的当前实例。@avlacatus是的,它会自动检测到它