How to auto scroll RecyclerView
smoothly so that user can see all the elements of the RecyclerView and scroll again from the start - as in News Feed etc.
I know smoothScrollToPosition()
and scrollToPosition()
but they would just end up scrolling too fast to the last element.
I want the RecyclerView to be animated and move slowly.
Just to improve on the answer a little, it's auto scrolling infinity with smooth animation.
final int speedScroll = 1200;
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
int count = 0;
boolean flag = true;
@Override
public void run() {
if(count < adapter.getItemCount()){
if(count==adapter.getItemCount()-1){
flag = false;
}else if(count == 0){
flag = true;
}
if(flag) count++;
else count--;
recyclerView.smoothScrollToPosition(count);
handler.postDelayed(this,speedScroll);
}
}
};
handler.postDelayed(runnable,speedScroll);
This is exactly your answer but if you link to more smooth animation then use LayoutManager
recyclerView.setLayoutManager(new CustomLinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false));
Control you animation changing MILLISECONDS_PER_INCH value.
public class CustomLinearLayoutManager extends LinearLayoutManager {
public CustomLinearLayoutManager(Context context) {
super(context);
}
public CustomLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public CustomLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
final LinearSmoothScroller linearSmoothScroller =
new LinearSmoothScroller(recyclerView.getContext()) {
private static final float MILLISECONDS_PER_INCH = 200f;
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return CustomLinearLayoutManager.this
.computeScrollVectorForPosition(targetPosition);
}
@Override
protected float calculateSpeedPerPixel
(DisplayMetrics displayMetrics) {
return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
}
};
linearSmoothScroller.setTargetPosition(position);
startSmoothScroll(linearSmoothScroller);
}
}
I think this is the best solution for this.
final int speedScroll = 150;
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
int count = 0;
@Override
public void run() {
if(count < list.size()){
recyclerView.scrollToPosition(++count);
handler.postDelayed(this,speedScroll);
}
}
};
handler.postDelayed(runnable,speedScroll);
After Trial And Errors This Works Perfect For Me
final RecyclerView mRecyclerViewr;
final ArrayList<String> stringArrayData = new ArrayList<String>
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.HORIZONTAL, false);
mRecyclerViewr.setLayoutManager(linearLayoutManager);
CustomAdapter customAdapter = new CustomAdapter(getApplicationContext(), topPriceBarList);
mRecyclerViewr.setAdapter(customAdapter);
// Auto Scroll Left To Right
final int scrollSpeed = 100; // Scroll Speed in Milliseconds
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
int x = 15; // Pixels To Move/Scroll
boolean flag = true;
// Find Scroll Position By Accessing RecyclerView's LinearLayout's Visible Item Position
int scrollPosition = linearLayoutManager.findLastCompletelyVisibleItemPosition();
int arraySize = stringArrayData.size(); // Gets RecyclerView's Adapter's Array Size
@Override
public void run() {
if (scrollPosition < arraySize) {
if (scrollPosition == arraySize - 1) {
flag = false;
} else if (scrollPosition <= 1) {
flag = true;
}
if (!flag) {
try {
// Delay in Seconds So User Can Completely Read Till Last String
TimeUnit.SECONDS.sleep(1);
mRecyclerViewr.scrollToPosition(0); // Jumps Back Scroll To Start Point
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// Know The Last Visible Item
scrollPosition = linearLayoutManager.findLastCompletelyVisibleItemPosition();
mRecyclerViewr.smoothScrollBy(x, 0);
handler.postDelayed(this, scrollSpeed);
}
}
};
handler.postDelayed(runnable, scrollSpeed);
This Will Auto Scroll Your RecyclerView To The End, Wait For a Second (So User Can Read Till End)
And Jumps/Scroll Back To First String In RecyclerView's Array List.
If You Want To Auto Scroll in Posetive And Negative direction You Just Need To Change The Condition Instead Of Using if(!flag) You Need To Set Value Of x in it
if (flag) x = 15;
else x= -15; // For Auto Scroll To Negative i.e Left Direction