【问题标题】:How to stop autoscroll recyclerview when data is loading from Firebase to Recyclerview through databaseReference.addValueEventListener当数据通过databaseReference.addValueEventListener从Firebase加载到Recyclerview时如何停止自动滚动recyclerview
【发布时间】:2021-06-05 03:43:45
【问题描述】:

我正在使用以下代码从 Firebase 设置 recyclerview。每次当新的孩子添加到firebase实时数据库并且recyclerview自动滚动到底部时,这都会获取整个数据。当用户在屏幕中间时,我需要停止 autoscroll recyclerview。

public void setUpRecyclerview() {
        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                modelList.clear();
                for (DataSnapshot ds:dataSnapshot.getChildren()) {
                    String data = (String) ds.child("data").getValue();
                    long time = (long) ds.child("time").getValue();
                    String type = (String) ds.child("type").getValue();
                    DealsModel model = new DealsModel(data, time, type);
                    modelList.add(model);
                    count++;
                }
                dealAdapter = new DealAdapter(modelList);
                LinearLayoutManager layoutManager = new LinearLayoutManager(DealsActivity.this);
                layoutManager.setStackFromEnd(true);
                recyclerView.setLayoutManager(layoutManager);
                recyclerView.setAdapter(dealAdapter);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });
    }

我只需要在插入新孩子时执行此功能,这样用户屏幕就不会自动滚动到底部,并且浮动按钮上的计数器会显示新消息出现。喜欢 Whatsapp/Telegram。


RecyclerView.LayoutManager linearLayoutManager = recyclerView.getLayoutManager();
                int lastVisiblePosition = ( (LinearLayoutManager) linearLayoutManager ).findLastCompletelyVisibleItemPosition();
                int position1 = ( (LinearLayoutManager) linearLayoutManager ).findLastVisibleItemPosition();

if(position1 != lastVisiblePosition ) {
                    if (positionStart >= (totalItem - 1)) {
                        countMsg = countMsg + 1;
                        Log.e("Countmsg","."+countMsg);
                    }
                }
                else {
                    recyclerView.scrollToPosition(totalItem - 1);
                }

我需要 positionStart 的值,即新插入的孩子的值。如何获得。

【问题讨论】:

    标签: android firebase firebase-realtime-database android-recyclerview


    【解决方案1】:

    如果您想更精细地控制对子节点的更改,请使用ChildEventListener

    databaseReference.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
            String data = dataSnapshot.child("data").getValue(String.class);
            long time = dataSnapshot.child("time").getValue(Long.class);
            String type = dataSnapshot.child("type").getValue(String.class);
            DealsModel model = new DealsModel(data, time, type);
            modelList.add(model);
            count++;
        }
    
        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
            Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());
        }
    
        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {
            Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());
        }
        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
            Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());
        }
    
        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.w(TAG, "onCancelled", databaseError.toException());
        }
    };
    

    这里的onChildAdded 方法最初为databaseReference 中的每个子节点调用,随后为每个添加的子节点调用一次。如您所见,您无需遍历ds.getChildren(),因为我们现在分别为每个子节点调用。

    由于除了添加之外还有更多类型的更改,您还需要实现onChildChangedonChildRemovedonChildMoved 以对您的数据结构进行相应的更新,然后调用adapter.notifyDataSetChanged() 告诉它是关于变化的。

    【讨论】:

    • 我不会更改现有的子数据。我需要检查应用程序运行时何时添加了新的孩子。
    • 我可以得到字符串 previousChildName 的位置
    • previousChildName 是添加/移动节点的子节点的键。如果你想找到previousChildName 的位置,你需要在某个地方已经有一个键的列表,这样你就可以在那里查找它。
    【解决方案2】:

    把这段代码去掉或者像这样弄成假的。

    layoutManager.setStackFromEnd(false);
    

    【讨论】:

    • 我想你不明白我的问题。我不想改变堆栈
    猜你喜欢
    • 2019-12-07
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 2017-06-12
    • 2016-07-17
    • 1970-01-01
    • 2017-02-10
    • 1970-01-01
    相关资源
    最近更新 更多