Diffutil in recycleview, making it autoscroll if a new item is added

老子叫甜甜 提交于 2019-12-19 05:08:08

问题


If we use DiffUtil.Callback, and do

adapter.setItems(itemList);
diff.dispatchUpdatesTo(adapter);

how can we make sure that adding of new elements will scroll to that new position.

I have a case where I see item disappear, and a new one is created as a first element at the top, but not visible. It is hidden on top until you scroll down to make it visible. Before using DiffUtil, I was implementing this manually, and after I knew I was inserting at some position (on top) I could scroll to.


回答1:


You have a dispatchUpdatesTo(ListUpdateCallback) method to use as well.

So you could just implement a ListUpdateCallback which gives you the first element inserted

class MyCallback implements ListUpdateCallback {
    int firstInsert = -1;
    Adapter adapter = null;
    void bind(Adapter adapter) {
        this.adapter = adapter;
    }
    public void onChanged(int position, int count, Object payload) {
        adapter.notifyItemRangeChanged(position, count, payload);
    }
    public void onInserted(int position, int count) {
        if (firstInsert == -1 || firstInsert > position) {
            firstInsert = position;
        }
        adapter.notifyItemRangeInserted(position, count);
    }
    public void onMoved(int fromPosition, int toPosition) {
        adapter.notifyItemMoved(fromPosition, toPosition);
    }
    public void onRemoved(int position, int count) {
        adapter.notifyItemRangeRemoved(position, count);
    }
}

and then just scroll the RecyclerView manually

myCallback.bind(adapter)
adapter.setItems(itemList);
diff.dispatchUpdatesTo(myCallback);
recycler.smoothScrollToPosition(myCallback.firstInsert);



回答2:


There's an easy way to do this that also preserves the user's scroll position if items are inserted outside the viewable area:

import android.os.Parcelable;

Parcelable recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState();
// apply diff result here (dispatch updates to the adapter)
recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);              

Using this approach, the new items are made visible if they are inserted where the user can see them -- but the user's viewpoint is preserved if the items are inserted outside of view.




回答3:


I used RecyclerView.AdapterDataObserver to detect when new items were added, and then scroll to the top of my list;

adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
    @Override
    public void onItemRangeInserted(int positionStart, int itemCount) {
        super.onItemRangeInserted(positionStart, itemCount);
        recycleView.smoothScrollToPosition(0);
    }
});


来源:https://stackoverflow.com/questions/43458146/diffutil-in-recycleview-making-it-autoscroll-if-a-new-item-is-added

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!