滚动提要时 RecyclerView 跳转到顶部

RecyclerView Jumps to Top when scrolling through feed

我正在开发西班牙语新闻应用程序,请参阅此处:

应用程序的问题是,每当任何用户点击喜欢、播放音频或翻译按钮时,recyclerView 都会跳到顶部。

可能的原因是因为更新帖子会触发 ValueEventListener 中的回调,用于填充此行中的 RecyclerView

mUSerCmt.orderByChild("timestamp").addValueEventListener( ... )

由于视图被完全清除并重新加载,它自然看起来好像已滚动到顶部。可以有多种方法来避免这种情况,具体的选择将取决于您的应用程序的更新需求。我能想到的一些是:

  1. 最好的选择是使用 DiffUtil 在不清除整个列表的情况下进行就地更新(使用动画),尽管在编码方面有点棘手。您应该能够找到许多关于如何在线使用 class 的简单教程。

  2. 使用addListenerForSingleValueEvent 以便对子项的更新不会触发列表的清除。这可能是一个糟糕的选择,因为您的应用显示的新闻可能经常更改。但是,如果用户经常切换屏幕(例如阅读新闻文章),那么刷新将发生足够多次,并且不会那么引人注目。获取文章时的分页也将确保最新的批次是最新的,而旧的可能有未同步的更改。

第一个选项是我推荐的选项,但第二个选项更易于编码,可用于解决问题,同时获得一些时间来正确实施 DiffUtil。

每当您设置新适配器时,RecyclerView 都会移除并分离旧适配器。相反,您可以尝试只更新当前适配器上的数据,一个简单的方法是在您的适配器上创建一个 public 方法来重新分配数据:

public class FeedAdapter extends RecyclerView.Adapter<FeedAdapter.FeedViewHolder> {
    // ...
    public void setItems(List<Object> items) {
        mRecyclerViewItems = items;
    }
    // ...
}

然后在 onDataChange 回调中更新您的适配器:

@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
    mRecyclerViewItems.clear();
    for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
        Model_Feed epiModel = dataSnapshot1.getValue(Model_Feed.class);
        mRecyclerViewItems.add(epiModel);
    }
    if (FeedAdapter != null) {
        FeedAdapter.setItems(mRecyclerViewItems);
        FeedAdapter. notifyDataSetChanged();
    } else {
        FeedAdapter = new FeedAdapter(mView.getContext(), mRecyclerViewItems);
        feedRecycler.setAdapter(FeedAdapter);
    }
}