Question
Recently I encountered a problem when writing SideBar. When executing the smoothScrollToPosition(position) of Recyclerview, the Recyclerview does not seem to scroll to the specified position.
Analysis
Of course, this is not a bug in the method, but there are three situations in the execution effect of smoothScrollToPosition(position) and it needs to be distinguished.
·The target position is before the first visible item.
In this case, call smoothScrollToPosition can be smoothly scrolled to the specified position and set the top.
·The target position is after the first visible item and before the last visible item.
In this case, calling smoothScrollToPosition will not have any effect...
·The target position is after the last visible item.
In this case, calling smoothScrollToPosition will slide the target item to the bottom of the screen...
Solution
Given these three situations, I think most of the time it doesn't meet our sliding requirements. In order to realize the requirement of Recyclerview to slide the specified item to the top of the screen, we need to deal with the above three situations separately.
/** Whether the target item is after the last visible item*/ private boolean mShouldScroll; /** Record the target item location*/ private int mToPosition; /** * Slide to the specified position * @param mRecyclerView * @param position */ private void smoothMoveToPosition(RecyclerView mRecyclerView, final int position) { // The first visible location int firstItem = ((0)); // The last visible location int lastItem = ((() - 1)); if (position < firstItem) { // If the jump position is before the first visible position, smoothScrollToPosition can be directly redirected (position); } else if (position <= lastItem) { // The jump position is after the first visible item and before the last visible item // smoothScrollToPosition will not move at all. At this time, call smoothScrollBy to slide to the specified position int movePosition = position - firstItem; if (movePosition >= 0 && movePosition < ()) { int top = (movePosition).getTop(); (0, top); } }else { // If the position to be redirected is after the last visible item, call smoothScrollToPosition first to scroll the position to be redirected to the visible position // Then, through onScrollStateChanged control, call smoothMoveToPosition again to execute the method in the previous judgment (position); mToPosition = position; mShouldScroll = true; } }
Then, through onScrollStateChanged control, call smoothMoveToPosition again
(new () { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { (recyclerView, newState); if (mShouldScroll){ mShouldScroll = false; smoothMoveToPosition(mRecyclerView,mToPosition); } } }); }
There are currently two known problems with this solution
1. When the target item is after the last visible item, since we first execute the smoothScrollToPosition method and then execute the smoothMoveToPosition method in the OnScrollListener, it is not coherent enough when sliding.
2. When performing this method when sliding manually, there will be a very small probability that the sliding position will be deviated.
If you have a better solution, I hope you will give me some advice.
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.