I have a Fragment with BottomSheet behavior that contains a horizontal RecyclerView. RecyclerView is adjusted by SnapHelper to achieve a page effect. It looks something like this:
In the onCreateView event in the Fragment, I set Adapter and LayoutManager:
recycler_view.setAdapter(new MyRecyclerAdapter(getContext(), dataList));
recycler_view.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
After I set Adapter, the onCreateViewHolder event is triggered in the MyRecyclerAdapter class object, followed by onBindViewHolder:
@Override
public MyRecyclerAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.fragment_recycler_item, parent, false);
return new MyViewHolder(view, parent);
}
@Override
public void onBindViewHolder(MyRecyclerAdapter.MyViewHolder viewHolder, int position) {
/**I do something using position**/
}
When I create this Fragment and configure RecyclerView for the first time-everything works well, onBindViewHolder returns the correct position. But when I flip to the 1st, 2nd, etc. element RecyclerView, and then recreate the fragment, for some unknown reason onBindViewHolder return the old (last) position, although a new Adapter and LineraLayoutManager were created.
To make it clear, I'll break it down into steps:
Question: Why do I get the old position and most importantly how do I fix it?
I read that Android specifically saves the old ViewHolder to use memory more efficiently, but I don't need it.
UPD (Solution): It seems to me that this is a temporary solution (not ideal), but it works. You need to run smoothScrollToPosition(0) after you have installed Adapter and LayoutManager. It is very important to use smoothScrollToPosition(0), not scrollToPosition(0):
recycler_view.setAdapter(new MyRecyclerAdapter(getContext(), dataList));
recycler_view.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
recycler_view.smoothScrollToPosition(0);
UPD.1 (Best Solution): Just use this:
recyclerView.setSaveEnabled(false);
If you detach and reattach the fragment then only its View hierarchy is being destroyed and recreated. Restoring scroll position is part of RecyclerView
s state restoration behavior.
If you want your RecyclerView
to always start at scroll 0 you can prevent it from saving its scroll state in the first place by disabling that behavior:
recyclerView.setSaveEnabled(false);