通过数据绑定控制视图可见性


<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <import type="android.view.View" />
        <variable
            name="notificationResponse"
            type="myms.models.NotificationResponse"/>
    </data>
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
...........
<TextView
        android:id="@+id/tv_empty_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/_12dp"
        android:layout_marginRight="@dimen/_12dp"
        android:minHeight="@dimen/_60dp"
        android:gravity="center"
        android:textSize="@dimen/_18sp"
        android:textStyle="bold"
        android:text="No Message"
        android:background="@color/white"
        android:visibility="@{notificationResponse.payloads.size() > 0 ? View.GONE : View.VISIBLE}"/>
......
</FrameLayout>
</layout>

我想要实现的是,默认情况下视图应该消失,在我的代码中实际绑定 notificationResponse 对象的异步调用之后,它应该决定是显示还是隐藏视图。

android:visibility="@{notificationResponse.payloads.size() > 0 ? View.GONE : View.VISIBLE}"编写的代码的解释是

当您的列表大小包含多个数据时,您希望隐藏该TextView,在其他情况下,您希望显示它。

不是在调用 API 时,列表大小肯定会小于或等于 0,因此它不可见。

溶液:

传递一些变量,指示 API 仍在后台调用,当 API 调用完成后,将该变量设置为 false。

android:visibility="@{notificationResponse.payloads.size() > 0 || !loading ? View.GONE : View.VISIBLE}"

这意味着,如果您的列表大小超过一个并且 API 调用已完成,TextView应该隐藏。

默认情况下,加载值应为 false,当您调用 API 时,将该值更改为 true,当 API 调用再次完成时,将其设置为 false。

在片段/活动中,您可以创建字段 int itemsCount = 0,在获得响应后,设置 itemsCount = response.payloads.size() 并在 xml 中设置 itemCount 而不是 NotificationResponse。

实际上,您必须在绑定中设置新变量才能对视图产生影响。这意味着,如果您想在不更改 xml 的情况下获得结果,只需设置新的列表,然后从响应中获取响应集列表。

编辑

第一种方法(根据下面的评论)是这样的:

public void setLoading(boolean loading) {
    isLoading = loading;
    notifyPropertyChanged(BR._all);
}

notifyPropertyChanged(BR.loading);

裁判

但是,有一种更简单的方法可以做到这一点,我会通过以下方式完成:首先在视图中更改此行

android:visibility="@{notificationResponse.payloads.size() > 0 ? View.GONE : View.VISIBLE}"/>

android:visibility="gone"/>

然后在您的 AsyncTask 中添加如下内容:

protected void onPostExecute(Boolean toBeShown) {
    if(toBeShown){
        tvEmptyView.setVisibility(View.VISIBLE);
    }else{
        tvEmptyView.setVisibility(View.GONE);
    }
}

另一种选择是使用绑定适配器。

@BindingAdapter("viewVisibility")
fun bindViewVisibility(view: View, shouldShow: Boolean) {
    view.let {
        if (shouldShow) {
            it.visibility = View.VISIBLE
        } else {
            it.visibility = View.GONE
        }
    }
}

在布局中:

<androidx.constraintlayout.widget.ConstraintLayout
   ...
   viewVisibility="@{viewModel.showError}"
   ...>
</androidx.constraintlayout.widget.ConstraintLayout>

最新更新