I want my RecyclerView with LinearLayoutManager to show up with scroll position at specific item after adapter got updated. (not first/last position) Means the at first (re-)lay
Another contribution to a long running question...
As mentioned, layoutManager.scrollToPosition/WithOffset()
does work to get the RecyclerView positioned, but timing this can be tricky. For example with variable length item views the RecyclerView has to work hard to get all the prior item views measured.
The approach below simply delays telling the RecyclerView about the prior items, then calls notifyItemRangeInserted(0, offset)
. This enabled the view to appear in the right place, with no visible scrolling at the start, and ready to scroll back.
private List bitmaps = new ArrayList<>();
...
private class ViewAdapter extends RecyclerView.Adapter {
private volatile int offset;
private boolean offsetCancelled;
ViewAdapter(int initialOffset) {
this.offset = initialOffset;
this.offsetCancelled = initialOffset > 0;
}
@Override
public int getItemCount() {
return bitmaps.size() - offset;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
ImageView imageView = new ImageView(MyActivity.this); // Or getContext() from a Fragment
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
imageView.setLayoutParams(lp);
return new ViewHolder(imageView);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.imageView.setImageBitmap(bitmaps.get(position + offset));
if (!offsetCancelled) {
offsetCancelled = true;
recyclerView.post(() -> {
int previousOffset = offset;
offset = 0;
notifyItemRangeInserted(0, previousOffset);
Log.i(TAG, "notifyItemRangeInserted(0, " + previousOffset + ")");
});
}
}
}
private class ViewHolder extends RecyclerView.ViewHolder {
private final ImageView imageView;
ViewHolder(@NonNull ImageView itemView) {
super(itemView);
this.imageView = itemView;
}
}
For context, this is a full example, based around ImageView's and Bitmap's. The key bit is the use of the offset in getItemCount()
and onBindViewHolder()
.