具有空视图的FirebaseRecyclerAdapter

Cha*_*har 16 android firebase android-recyclerview firebase-realtime-database firebaseui

我知道有很多方法可以为RecyclerView提供一个空视图.但我的问题是针对FirebaseRecyclerView.

我的布局是:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

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

<ProgressBar
    android:id="@+id/feed_loading"
    style="?android:attr/progressBarStyle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:visibility="gone"/>
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

所以我在RecyclerView填充其项目之前显示正在加载ProgressBar.现在如果服务器没有任何项目怎么办?在这种情况下,我的RecyclerView始终为空,我的Loading ProgressBar始终对用户可见.

因此,我希望显示一些空布局,而不是无限期地显示ProgressBar.例如"找不到数据"或类似的消息.

最终结果应该是:ProgressBar应该显示,直到数据加载到RecyclerView,一旦数据加载,ProgressBar应该是不可见的.但是如果服务器中没有数据,则应显示一些空布局而不是ProgressBar.

在普通的RecyclerView中,我们有一个数据集(某些ArrayList等),如果它是空的,那么我们可以显示那个空布局.但是对于FirebaseRecyclerAdapter,我在我的Activity或Context中没有Snapshot的引用.我也没有任何回调告诉我服务器中没有数据.

任何解决方法都会有很大帮助.

Kev*_*eil 24

这是我会尝试的.首先查看下面链接问题的已接受答案.它提供了一些非常好的洞察Firebase查询的工作方式.我认为信息是受信任的,因为答案是Firebase团队的某个人:

如何使用Firebase将初始数据加载与增量子级分开?

因此,基于上面链接的问题的答案以及FirebaseRecyclerAdapterFirebaseArray使用ChildEventListenerI 填充的事实支持的事实,我将在用于填充您的相同数据库引用上添加Single值事件侦听器FirebaseRecyclerAdapter.像这样的东西:

//create database reference that will be used for both the
//FirebaseRecyclerAdapter and the single value event listener
dbRef = FirebaseDatabase.getInstance().getReference();

//setup FirebaseRecyclerAdapter
mAdapter = new FirebaseRecyclerAdapter<Model, YourViewHolder>(
                Model.class, R.layout.your_layout, YourViewHolder.class, dbRef) {

                @Override
                public void populateViewHolder(YourViewHolder holder, Model model, int position){

                     //your code for populating each recycler view item

                };

mRecyclerView.setAdapter(mAdapter);

//add the listener for the single value event that will function
//like a completion listener for initial data load of the FirebaseRecyclerAdapter
dbRef.addListenerForSingleValueEvent(new ValueEventListener() {
             @Override
             public void onDataChange(DataSnapshot dataSnapshot) {
                 //onDataChange called so remove progress bar

                 //make a call to dataSnapshot.hasChildren() and based 
                 //on returned value show/hide empty view 

                 //use helper method to add an Observer to RecyclerView    
             }

             @Override
             public void onCancelled(DatabaseError databaseError) {

             }
      });
Run Code Online (Sandbox Code Playgroud)

这将处理RecyclerView的初始设置.在onDataChange单值事件侦听器上调用时,使用辅助方法将观察器添加到FirebaseRecyclerAdapter以处理对数据库位置的任何后续添加/删除.

mObserver = new RecyclerView.AdapterDataObserver() {
            @Override
            public void onItemRangeInserted(int positionStart, int itemCount) {
                //perform check and show/hide empty view
            }

            @Override
            public void onItemRangeRemoved(int positionStart, int itemCount) {
                //perform check and show/hide empty view
            }
           };
mAdapter.registerAdapterDataObserver(mObserver);
Run Code Online (Sandbox Code Playgroud)


小智 5

答案来自:https : //stackoverflow.com/a/40204298/2170278

如今,FirebaseUI适配器具有一种onDataChanged()可以重写的方法,以检测它们何时完成加载一组数据。

请参阅github上源代码。从那里:

每当数据库的更新已被完全处理时,将触发此方法。因此,第一次调用此方法时,初始数据已加载-包括根本没有数据可用的情况。每次下一次调用该方法时,完整的更新(可能包含对多个子项的更新)已经完成。

通常,您将重写此方法以隐藏加载指示符(在初始加载之后)或完成对UI元素的批量更新。

FirebaseUI示例应用程序将覆盖onDataChanged()以隐藏其“正在加载”指示器:

public void onDataChanged() {
    // If there are no chat messages, show a view that invites the user to add a message.
    mEmptyListMessage.setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE);
}
Run Code Online (Sandbox Code Playgroud)