如果Recyclerview为空,则隐藏视图

时间:2018-03-29 07:25:28

标签: android android-recyclerview

我在这种布局中有一个RecyclerView和其他小部件:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="in.joey.joseph.aapnidukan.activities.CheckOutActivity">

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@color/colorPrimary"
    android:minHeight="?attr/actionBarSize">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/backIV"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:srcCompat="@drawable/back_image"
            android:padding="16dp"
            android:layout_centerVertical="true"
            android:layout_alignParentLeft="true"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="CheckOut"
            android:textSize="18sp"
            android:fontFamily="casual"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true"
            android:gravity="center"
            android:textColor="@android:color/white"/>

    </RelativeLayout>

</android.support.v7.widget.Toolbar>

<RelativeLayout
    android:id="@+id/nonEmptyState"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/toolbar"
    android:visibility="visible">

    <in.joey.joseph.aapnidukan.utils.EmptyRecyclerView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/checkOutRV"
        />

    <RelativeLayout
        android:id="@+id/cartTotalLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/checkOutRV"
        android:layout_alignParentRight="true"
        android:gravity="right"
        android:layout_marginRight="20dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:gravity="right"
            android:layout_marginRight="20dp"
            android:padding="10dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Total: "
                android:textSize="18sp"
                android:textColor="@android:color/black"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="&#8377;"
                android:textSize="18sp"
                android:textColor="@android:color/black"
                android:layout_marginLeft="10dp"/>

            <TextView
                android:id="@+id/totalPriceTV"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                tools:text="8999"
                android:textSize="18sp"
                android:textColor="@color/colorPrimary"
                android:layout_marginLeft="5dp"/>

        </LinearLayout>

    </RelativeLayout>

    <Button
        android:id="@+id/billingBtn"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:background="@color/colorAccent"
        android:text="Proceed to Billing and Address"
        android:textColor="@android:color/white"
        android:textAllCaps="false"
        android:textSize="20sp"
        android:layout_alignParentBottom="true"/>

</RelativeLayout>

<TextView
    android:id="@+id/emptyState"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Add Items to Cart Before CheckOut"
    android:textSize="18sp"
    android:fontFamily="casual"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true"
    android:gravity="center"
    android:textColor="@android:color/black"
    android:visibility="visible"/>

我创建了一个自定义RecyclerView来处理空状态,但它只适用于RecyclerView。当列表为空时,其他视图(如按钮)仍然可见。我试图将其隐藏在我的自定义RecyclerView类中,如下所示:

private void checkNotEmpty(){
    if (nonEmptyView != null && getAdapter() != null){
        boolean nonEmptyViewVisible = getAdapter().getItemCount() > 0;
        nonEmptyView.setVisibility(nonEmptyViewVisible ? VISIBLE : GONE);
        setVisibility(nonEmptyViewVisible ? GONE : VISIBLE);
    }
}

以下是RecyclerView的完整类代码:

public class EmptyRecyclerView extends RecyclerView {

private View emptyView, nonEmptyView;

public EmptyRecyclerView(Context context) {
    super(context);
}

public EmptyRecyclerView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
}

public EmptyRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

private final AdapterDataObserver dataObserver = new AdapterDataObserver() {
    @Override
    public void onChanged() {
        checkEmpty();
    }

    @Override
    public void onItemRangeInserted(int positionStart, int itemCount) {
        checkEmpty();
    }

    @Override
    public void onItemRangeRemoved(int positionStart, int itemCount) {
        checkEmpty();
    }
};

private void checkEmpty() {
    if (emptyView != null && getAdapter() != null){
        boolean emptyViewVisible = getAdapter().getItemCount() == 0;
        emptyView.setVisibility(emptyViewVisible ? VISIBLE : GONE);
        setVisibility(emptyViewVisible ? GONE : VISIBLE);
    }
}

private void checkNotEmpty(){
    if (nonEmptyView != null && getAdapter() != null){
        boolean nonEmptyViewVisible = getAdapter().getItemCount() > 0;
        nonEmptyView.setVisibility(nonEmptyViewVisible ? VISIBLE : GONE);
        setVisibility(nonEmptyViewVisible ? GONE : VISIBLE);
    }
}

public void setButtonVisibility(Button button){ // to toggle the button visibility
    if (getAdapter().getItemCount() > 0){
        button.setVisibility(View.VISIBLE);
    } else {
        button.setVisibility(GONE);
    }
}

@Override
public void setAdapter(Adapter adapter) {
    Adapter oldAdapter = getAdapter();
    if (oldAdapter != null){
        oldAdapter.unregisterAdapterDataObserver(dataObserver);
    }
    super.setAdapter(adapter);
    if (adapter != null){
        adapter.registerAdapterDataObserver(dataObserver);
    }

    checkEmpty();
}

public void setEmptyView(View view){
    this.emptyView = view;
    checkEmpty();
}

public void setNonEmptyView(View view2){
    this.nonEmptyView = view2;
    checkNotEmpty();
}

}

在我的活动中,我尝试过这个:

    init();
    checkOutRV.setEmptyView(emptyState);
    checkOutRV.setNonEmptyView(nonEmptyState);

    private void init() {
    nonEmptyState = findViewById(R.id.nonEmptyState);
    emptyState = findViewById(R.id.emptyState);
    checkOutRV = findViewById(R.id.checkOutRV);

    checkOutRV.setHasFixedSize(true);
    checkOutRV.setLayoutManager(new LinearLayoutManager(this));

}

该列表现在没有数据,因为我尚未进行API调用,但仍然可以看到emptyStateTextView和按钮。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:0)

试试这个:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout >

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        >

        ...

    </android.support.v7.widget.Toolbar>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/toolbar"
        android:visibility="visible">

        <RelativeLayout
            android:id="@+id/nonEmptyState"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <!-- Existing layout like recyclerview, button -->
        </RelativeLayout>


        <RelativeLayout
            android:id="@+id/emptyStateLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:id="@+id/emptyState"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:fontFamily="casual"
                android:gravity="center"
                android:text="Add Items to Cart Before CheckOut"
                android:textColor="@android:color/black"
                android:textSize="18sp"
                android:visibility="visible"/>
        </RelativeLayout>

    </RelativeLayout>
</RelativeLayout>

VISIBLE为空时,只需设置 emptyStateLayout RecyclerView,否则GONE

答案 1 :(得分:0)

在checkNonEmpty()方法中,您调用了 getAdapter(),它返回null,因为您没有在回收站视图上使用setAdapter()。

为您的回收站视图创建一个适配器,并使用空列表初始化它,然后在视图上设置setAdapter()。

然后你可以使用这些陈述

  checkOutRV.setEmptyView(emptyState);
  checkOutRV.setNonEmptyView(nonEmptyState); 

希望它有所帮助!!

答案 2 :(得分:0)

默认保留您的布局INVISIBLE并显示一个布局,显示Recyclerview没有数据或其他内容,然后当您进行API调用并接收数据时,隐藏显示的布局将recyclerview设置为空,并将数据布局视图设置为要显示的VISIBLE

更新的答案

您需要注册数据观察器以侦听来自同步适配器的数据更改。

mRecyclerViewAdapter.registerAdapterDataObserver(myObserver);

RecyclerView.AdapterDataObserver是您调用的通知方法的结果。因此,例如,如果在向适配器添加项目后调用notifyItemInserted(),则会调用onItemRangeInserted()

更详细的例子

protected void setupRecyclerView() {
    mAdapter = new MyAdapter(mItemList);
    mAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
        @Override
        public void onChanged() {
            super.onChanged();
            checkAdapterIsEmpty();
        }
    });

    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    mRecyclerView.setHasFixedSize(true);

    mRecyclerView.setAdapter(mAdapter);
    checkAdapterIsEmpty();
}

另外,不要忘记取消注册观察者。