我习惯于在布局文件中放置一个特殊的视图,如ListActivity文档中所述,在没有数据时显示。这个视图的id为“android:id/empty”。

<TextView
    android:id="@android:id/empty"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/no_data" />

我想知道这如何能与新的RecyclerView?


当前回答

在适配器的getItemViewType上检查适配器是否有0个元素,如果是,则返回不同的viewType。

然后在onCreateViewHolder上检查viewType是否为之前返回的视图,并膨胀一个不同的视图。在这种情况下,布局文件与该TextView

编辑

如果这仍然不能工作,那么你可能想通过编程来设置视图的大小,就像这样:

Point size = new Point();
((WindowManager)itemView.getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(size);

然后当你膨胀你的视图调用:

inflatedView.getLayoutParams().height = size.y;
inflatedView.getLayoutParams().width = size.x;

其他回答

如果你正在使用FirebaseRecyclerAdapter,这篇文章就像一个魅力https://stackoverflow.com/a/39058636/6507009

另一种方法是使用addOnChildAttachStateChangeListener来处理RecyclerView中出现/消失的子视图。

recyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {
            @Override
            public void onChildViewAttachedToWindow(@NonNull View view) {
                forEmptyTextView.setVisibility(View.INVISIBLE);
            }

            @Override
            public void onChildViewDetachedFromWindow(@NonNull View view) {
                forEmptyTextView.setVisibility(View.VISIBLE);
            }
        });

在适配器的getItemViewType上检查适配器是否有0个元素,如果是,则返回不同的viewType。

然后在onCreateViewHolder上检查viewType是否为之前返回的视图,并膨胀一个不同的视图。在这种情况下,布局文件与该TextView

编辑

如果这仍然不能工作,那么你可能想通过编程来设置视图的大小,就像这样:

Point size = new Point();
((WindowManager)itemView.getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(size);

然后当你膨胀你的视图调用:

inflatedView.getLayoutParams().height = size.y;
inflatedView.getLayoutParams().width = size.x;

在定义了RecyclerView的相同布局上,添加TextView:

<android.support.v7.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical" />

<TextView
    android:id="@+id/empty_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:visibility="gone"
    android:text="@string/no_data_available" />

在onCreate或适当的回调中,您检查提供RecyclerView的数据集是否为空。 如果数据集为空,那么RecyclerView也是空的。在这种情况下,消息将显示在屏幕上。 如果不是,改变它的可见性:

private RecyclerView recyclerView;
private TextView emptyView;

// ...

recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
emptyView = (TextView) rootView.findViewById(R.id.empty_view);

// ...

if (dataset.isEmpty()) {
    recyclerView.setVisibility(View.GONE);
    emptyView.setVisibility(View.VISIBLE);
}
else {
    recyclerView.setVisibility(View.VISIBLE);
    emptyView.setVisibility(View.GONE);
}

RVEmptyObserver

而不是使用自定义的RecyclerView,扩展AdapterDataObserver是一个更简单的解决方案,允许设置一个自定义视图,当列表中没有项目时显示:

使用示例:

RVEmptyObserver observer = new RVEmptyObserver(recyclerView, emptyView)
rvAdapter.registerAdapterDataObserver(observer);

类:

public class RVEmptyObserver extends RecyclerView.AdapterDataObserver {
    private View emptyView;
    private RecyclerView recyclerView;

    public RVEmptyObserver(RecyclerView rv, View ev) {
        this.recyclerView = rv;
        this.emptyView    = ev;
        checkIfEmpty();
    }

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

    public void onChanged() { checkIfEmpty(); }
    public void onItemRangeInserted(int positionStart, int itemCount) { checkIfEmpty(); }
    public void onItemRangeRemoved(int positionStart, int itemCount) { checkIfEmpty(); }
}